// File: /workspace/github_cpp_makefile_star2_O2/waket[P]ThreadPool/ThreadPoolTask.cpp
// Function: ThreadPoolTask::startWorker()
void ThreadPoolTask::startWorker() {
    pthread_t id = pthread_self();
    cout << "\tStart the worker: " << id << endl;

    startWorkersMutex.lock();
    workersSet.insert(id);
    // Check if all the workers have started then unblock startWorkersCond
    if (workersSet.size() == workerCount) {
        cout << "\t" << id << " All workers started wakeup startWorkersCond" << endl;
        startWorkersCond.signal();
    }
    startWorkersMutex.unlock();

    while (true) {
        cout << "\t" << id << " waiting for the release of the lock" << endl;
        tasksMutex.lock();
        cout << "\t" << id << " is locked " <<tasksDeque.size() << " " << isStarted << " " << isStopWorker << endl;
        // Wait if no task to do and the thread pool is not stopped 
        while (tasksDeque.empty() && isStarted && !isStopWorker) {
            // The wait will be released due to availability of a new task 
            // (signal() from doTask()) or due to the stooping of the
            // pool (broadcast() from stop())
            // The Wait will release the unlock of the mutex tasksMutex and lock it
            // back as soon as it is signaled
            cout << "\t" << id << " is waiting" << endl;
            tasksCond.wait(tasksMutex.mutexPtr());
            cout << "\t" << id << " is signaled " << isStarted << " " << isStopWorker << endl;
        }

        // Check if the thread pool is still on
        if (!isStarted) {
            cout << "\t" << id << " exit (thread pool is stopped) " << workersSet.size() << endl;
            tasksMutex.unlock();
            pthread_exit(NULL);
        }

        // Check for dynamic count worker
        if (isStopWorker) {
            assert(workersSet.size() != workerCount);
            workersSet.erase(id);
            tasksCond.signal();
            if (workersSet.size() == workerCount) {
                isStopWorker = false;
                cout << "\t" << id << " is the last exiting worker " << workersSet.size() << " " << isStopWorker << endl;
                // Unblock setWorkerCount()
                stopWorkersCond.signal();
            }
            cout << "\t" << id << " exit (reduce the worker count) " << workersSet.size() << endl;
            tasksMutex.unlock();
            pthread_exit(NULL);
        }

        assert(!tasksDeque.empty());

        // pick a task
        TaskItem task = tasksDeque.front();
        tasksDeque.pop_front();
        cout << "\t" << id << " pop. Size of the task queue is: " << tasksDeque.size() << endl;
        tasksMutex.unlock();
        // do the task
        (task) ();
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
callq 0x2160
movq %rax, %r14
movq %rsp, %r15
movq %rax, (%r15)
movq 0x50d2(%rip), %rdi      # 0x7fd8
leaq 0x2395(%rip), %rsi      # 0x52a2
callq 0x21a0
movq %rax, %rdi
movq %r14, %rsi
callq 0x2100
movq %rax, %rdi
callq 0x20a0
leaq 0x158(%rbx), %r14
movq %r14, %rdi
callq 0x3936
leaq 0x60(%rbx), %rdi
movq %rdi, 0x10(%rsp)
movq %r15, %rsi
callq 0x3b54
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x2f94
movq 0x507f(%rip), %rdi      # 0x7fd8
leaq 0x2356(%rip), %rsi      # 0x52b6
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
leaq 0x2340(%rip), %rsi      # 0x52b8
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20a0
leaq 0x188(%rbx), %rdi
callq 0x2030
movq %r14, %rdi
callq 0x3946
leaq 0x90(%rbx), %r14
leaq 0x10(%rbx), %rax
movq %rax, 0x8(%rsp)
leaq 0xc0(%rbx), %r12
movq 0x501e(%rip), %rbp      # 0x7fd8
leaq 0x22f5(%rip), %r15      # 0x52b6
movq %rbp, %rdi
movq %r15, %rsi
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0x2303(%rip), %rsi      # 0x52e5
callq 0x21a0
movq %rax, %rdi
callq 0x20a0
movq %r14, %rdi
callq 0x3936
movq %rbp, %rdi
movq %r15, %rsi
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0x22f2(%rip), %rsi      # 0x530a
callq 0x21a0
movq %rax, %r13
movq 0x8(%rsp), %rdi
callq 0x3950
movq %r13, %rdi
movq %rax, %rsi
callq 0x2100
movq %rax, %rdi
leaq 0x230f(%rip), %rsi      # 0x534e
callq 0x21a0
movzbl 0x150(%rbx), %esi
movq %rax, %rdi
callq 0x22b0
movq %rax, %rdi
leaq 0x22f1(%rip), %rsi      # 0x534e
callq 0x21a0
movzbl 0x152(%rbx), %esi
movq %rax, %rdi
callq 0x22b0
movq %rax, %rdi
callq 0x20a0
movq 0x20(%rbx), %rsi
movq 0x40(%rbx), %rax
movb 0x150(%rbx), %cl
cmpq %rsi, %rax
jne 0x30fd
testb $0x1, %cl
je 0x31a5
cmpb $0x0, 0x152(%rbx)
jne 0x3114
movq %rbp, %rdi
movq %r15, %rsi
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0x2257(%rip), %rsi      # 0x5316
callq 0x21a0
movq %rax, %rdi
callq 0x20a0
movq %r12, %rdi
movq %r14, %rsi
callq 0x2270
movq %rbp, %rdi
movq %r15, %rsi
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0x222a(%rip), %rsi      # 0x5322
jmp 0x303f
testb $0x1, %cl
je 0x31a5
cmpb $0x1, 0x152(%rbx)
jne 0x312a
jmp 0x31f9
cmpb $0x0, 0x152(%rbx)
jne 0x31f9
cmpq %rsi, %rax
je 0x32e5
leaq 0x18(%rsp), %rdi
callq 0x3e8e
movq 0x8(%rsp), %rdi
callq 0x3960
movq %rbp, %rdi
movq %r15, %rsi
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0x229a(%rip), %rsi      # 0x53f9
callq 0x21a0
movq %rax, %r13
movq 0x8(%rsp), %rdi
callq 0x3950
movq %r13, %rdi
movq %rax, %rsi
callq 0x2100
movq %rax, %rdi
callq 0x20a0
movq %r14, %rdi
callq 0x3946
leaq 0x18(%rsp), %rdi
callq 0x398a
leaq 0x18(%rsp), %rdi
callq 0x2a7a
jmp 0x2fc1
movq 0x4e2c(%rip), %rdi      # 0x7fd8
leaq 0x2103(%rip), %rsi      # 0x52b6
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2050
leaq 0x2165(%rip), %rsi      # 0x5330
movq %rax, %rdi
callq 0x21a0
movq 0x88(%rbx), %rsi
movq %rax, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20a0
movq %r14, %rdi
callq 0x3946
xorl %edi, %edi
callq 0x22f0
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x3222
leaq 0x2143(%rip), %rdi      # 0x5350
leaq 0x215d(%rip), %rsi      # 0x5371
leaq 0x2169(%rip), %rcx      # 0x5384
pushq $0x58
jmp 0x32fc
movq %rsp, %rsi
movq 0x10(%rsp), %rdi
callq 0x3ce6
movq %r12, %rdi
callq 0x2030
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x32ba
movb $0x0, 0x152(%rbx)
movq 0x4d86(%rip), %rdi      # 0x7fd8
leaq 0x205d(%rip), %rsi      # 0x52b6
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2100
leaq 0x2136(%rip), %rsi      # 0x53a7
movq %rax, %rdi
callq 0x21a0
movq 0x88(%rbx), %rsi
movq %rax, %rdi
callq 0x2100
leaq 0x20bf(%rip), %rsi      # 0x534e
movq %rax, %rdi
callq 0x21a0
movzbl 0x152(%rbx), %esi
movq %rax, %rdi
callq 0x22b0
movq %rax, %rdi
callq 0x20a0
leaq 0x1e8(%rbx), %rdi
callq 0x2030
movq 0x4d17(%rip), %rdi      # 0x7fd8
leaq 0x1fee(%rip), %rsi      # 0x52b6
callq 0x21a0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0x2050
leaq 0x20e4(%rip), %rsi      # 0x53c4
jmp 0x31cb
leaq 0x20f9(%rip), %rdi      # 0x53e5
leaq 0x207e(%rip), %rsi      # 0x5371
leaq 0x208a(%rip), %rcx      # 0x5384
pushq $0x66
popq %rdx
callq 0x20f0
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x2a7a
movq %rbx, %rdi
callq 0x22e0
nop