// File: wellenvogel[P]simple-cpp-threads/test.cpp
// Function: main
int main(int argc, char ** argv){
	cout << "hello world" << endl;
        int numThreads=5;
        if (argc > 1){
            numThreads=atoi(argv[1]);
        }
        vector<MyRunnable*> runnables;
        for (int i=0;i< numThreads;i++){
            MyRunnable *runnable=new MyRunnable(i);
            Thread *t=new Thread(runnable);
            t->start();
            runnables.push_back(runnable);
        }
        //"misuse" of a condition for ms waits
        Condition waiter;
        //waiting for start
        bool allRunning=false;
        cout << "waiting for threads to start" << endl;
        while (! allRunning){
            allRunning=true;
            vector<MyRunnable*>::iterator it=runnables.begin();
            while (it != runnables.end()){
                if ((*it)->getState() != RUNNING) {
                    cout << "##state "<<((*it)->getId())<<" is "<<((*it)->getState())<<endl;
                    allRunning=false;
                }
                it++;
            }
            waiter.wait(20); //avoid busy loop
        }
        cout << numThreads << " are running" <<endl;
        waiter.wait(10000);
        cout << "stopping" << endl;
        vector<MyRunnable*>::iterator it=runnables.begin();
        while (it != runnables.end()){
            (*it)->setState(STOP);
            it++;
        }
        bool allStopped=false;
        int maxWait=50*10; //max 10s
        while (! allStopped && maxWait){
            allStopped=true;
            vector<MyRunnable*>::iterator it=runnables.begin();
            while (it != runnables.end()){
                if ((*it)->getState() != STOP) allStopped=false;
                it++;
            }
            maxWait--;
            waiter.wait(20); //avoid busy loop
        }
        if (allStopped) cout << "all threads stopped" << endl;
        else cout << "unable to stop all threads" << endl;
        //if we would like to wait here for all threads
        //we also would need to keep the thread objects...
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x5ca8(%rip), %rdi      # 0x7fd8
leaq 0x2ccd(%rip), %rsi      # 0x5004
callq 0x2100
movq %rax, %rdi
movq 0x5c7a(%rip), %rsi      # 0x7fc0
callq 0x2120
movl $0x5, -0x14(%rbp)
cmpl $0x1, -0x8(%rbp)
jle 0x2368
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x2170
movl %eax, -0x14(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2950
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2458
movl $0x48, %edi
callq 0x2110
movq %rax, -0xf8(%rbp)
jmp 0x2397
movq -0xf8(%rbp), %rdi
movl -0x34(%rbp), %esi
callq 0x2970
jmp 0x23a8
movq -0xf8(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x10, %edi
callq 0x2110
movq %rax, -0x100(%rbp)
jmp 0x23c6
movq -0x100(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x2a10
jmp 0x23d8
movq -0x100(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x2a40
jmp 0x23ee
leaq -0x30(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x2ac0
jmp 0x23fd
jmp 0x23ff
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x2378
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x28a6
movq -0xf8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0x20f0
jmp 0x28a6
movq -0x100(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0x20f0
jmp 0x28a6
leaq -0x98(%rbp), %rdi
callq 0x2b30
jmp 0x2466
movb $0x0, -0x99(%rbp)
movq 0x5b64(%rip), %rdi      # 0x7fd8
leaq 0x2b95(%rip), %rsi      # 0x5010
callq 0x2100
movq %rax, -0x108(%rbp)
jmp 0x2489
movq -0x108(%rbp), %rdi
movq 0x5b29(%rip), %rsi      # 0x7fc0
callq 0x2120
jmp 0x249e
jmp 0x24a0
movb -0x99(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x24b1
jmp 0x2632
movb $0x1, -0x99(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2bc0
movq %rax, -0xa8(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2c30
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x2bf0
testb $0x1, %al
jne 0x24f4
jmp 0x261a
leaq -0xa8(%rbp), %rdi
callq 0x2c60
movq (%rax), %rdi
callq 0x2c80
movl %eax, -0x10c(%rbp)
jmp 0x2510
movl -0x10c(%rbp), %eax
cmpl $0x1, %eax
je 0x2600
movq 0x5ab2(%rip), %rdi      # 0x7fd8
leaq 0x2b00(%rip), %rsi      # 0x502d
callq 0x2100
movq %rax, -0x118(%rbp)
jmp 0x253b
leaq -0xa8(%rbp), %rdi
callq 0x2c60
movq (%rax), %rdi
callq 0x2cc0
movl %eax, -0x11c(%rbp)
jmp 0x2557
movl -0x11c(%rbp), %esi
movq -0x118(%rbp), %rdi
callq 0x21a0
movq %rax, -0x128(%rbp)
jmp 0x2572
movq -0x128(%rbp), %rdi
leaq 0x2ab6(%rip), %rsi      # 0x5036
callq 0x2100
movq %rax, -0x130(%rbp)
jmp 0x258e
leaq -0xa8(%rbp), %rdi
callq 0x2c60
movq (%rax), %rdi
callq 0x2c80
movl %eax, -0x134(%rbp)
jmp 0x25aa
movl -0x134(%rbp), %esi
movq -0x130(%rbp), %rdi
callq 0x21a0
movq %rax, -0x140(%rbp)
jmp 0x25c5
movq -0x140(%rbp), %rdi
movq 0x59ed(%rip), %rsi      # 0x7fc0
callq 0x2120
jmp 0x25da
movb $0x0, -0x99(%rbp)
jmp 0x2600
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x2e10
jmp 0x28a6
leaq -0xa8(%rbp), %rdi
xorl %esi, %esi
callq 0x2ce0
movq %rax, -0xb8(%rbp)
jmp 0x24c8
leaq -0x98(%rbp), %rdi
movl $0x14, %esi
callq 0x2d20
jmp 0x262d
jmp 0x24a0
movl -0x14(%rbp), %esi
movq 0x599c(%rip), %rdi      # 0x7fd8
callq 0x21a0
movq %rax, -0x148(%rbp)
jmp 0x264a
movq -0x148(%rbp), %rdi
leaq 0x29e3(%rip), %rsi      # 0x503b
callq 0x2100
movq %rax, -0x150(%rbp)
jmp 0x2666
movq -0x150(%rbp), %rdi
movq 0x594c(%rip), %rsi      # 0x7fc0
callq 0x2120
jmp 0x267b
leaq -0x98(%rbp), %rdi
movl $0x2710, %esi           # imm = 0x2710
callq 0x2d20
jmp 0x268e
movq 0x5943(%rip), %rdi      # 0x7fd8
leaq 0x29ac(%rip), %rsi      # 0x5048
callq 0x2100
movq %rax, -0x158(%rbp)
jmp 0x26aa
movq -0x158(%rbp), %rdi
movq 0x5908(%rip), %rsi      # 0x7fc0
callq 0x2120
jmp 0x26bf
leaq -0x30(%rbp), %rdi
callq 0x2bc0
movq %rax, -0xc0(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2c30
movq %rax, -0xc8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x2bf0
testb $0x1, %al
jne 0x26f8
jmp 0x272a
leaq -0xc0(%rbp), %rdi
callq 0x2c60
movq (%rax), %rdi
movl $0x2, %esi
callq 0x2da0
jmp 0x2713
leaq -0xc0(%rbp), %rdi
xorl %esi, %esi
callq 0x2ce0
movq %rax, -0xd0(%rbp)
jmp 0x26cf
movb $0x0, -0xd1(%rbp)
movl $0x1f4, -0xd8(%rbp)     # imm = 0x1F4
xorl %eax, %eax
testb $0x1, -0xd1(%rbp)
movb %al, -0x159(%rbp)
jne 0x275c
cmpl $0x0, -0xd8(%rbp)
setne %al
movb %al, -0x159(%rbp)
movb -0x159(%rbp), %al
testb $0x1, %al
jne 0x276b
jmp 0x2816
movb $0x1, -0xd1(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2bc0
movq %rax, -0xe0(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2c30
movq %rax, -0xe8(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x2bf0
testb $0x1, %al
jne 0x27ab
jmp 0x27f0
leaq -0xe0(%rbp), %rdi
callq 0x2c60
movq (%rax), %rdi
callq 0x2c80
movl %eax, -0x160(%rbp)
jmp 0x27c7
movl -0x160(%rbp), %eax
cmpl $0x2, %eax
je 0x27d9
movb $0x0, -0xd1(%rbp)
leaq -0xe0(%rbp), %rdi
xorl %esi, %esi
callq 0x2ce0
movq %rax, -0xf0(%rbp)
jmp 0x2782
movl -0xd8(%rbp), %eax
decl %eax
movl %eax, -0xd8(%rbp)
leaq -0x98(%rbp), %rdi
movl $0x14, %esi
callq 0x2d20
jmp 0x2811
jmp 0x273b
testb $0x1, -0xd1(%rbp)
je 0x2852
movq 0x57b2(%rip), %rdi      # 0x7fd8
leaq 0x2824(%rip), %rsi      # 0x5051
callq 0x2100
movq %rax, -0x168(%rbp)
jmp 0x283b
movq -0x168(%rbp), %rdi
movq 0x5777(%rip), %rsi      # 0x7fc0
callq 0x2120
jmp 0x2850
jmp 0x2885
movq 0x577f(%rip), %rdi      # 0x7fd8
leaq 0x2805(%rip), %rsi      # 0x5065
callq 0x2100
movq %rax, -0x170(%rbp)
jmp 0x286e
movq -0x170(%rbp), %rdi
movq 0x5744(%rip), %rsi      # 0x7fc0
callq 0x2120
jmp 0x2883
jmp 0x2885
leaq -0x98(%rbp), %rdi
callq 0x2e10
leaq -0x30(%rbp), %rdi
callq 0x2e60
movl -0x4(%rbp), %eax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x2e60
movq -0x48(%rbp), %rdi
callq 0x21b0
nopl (%rax,%rax)