// File: /workspace/github_cpp_makefile_star2_O1/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 $0x48, %rsp
movq %rdi, %rbx
callq 0x2180
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
movq 0x4c1b(%rip), %r14      # 0x7fd8
leaq 0x1ee2(%rip), %rsi      # 0x52a6
movl $0x13, %edx
movq %r14, %rdi
callq 0x2220
movq (%r15), %rsi
movq %r14, %rdi
callq 0x2110
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x158(%rbx), %r14
movq %r14, %rdi
callq 0x2290
movb $0x1, 0x180(%rbx)
leaq 0x60(%rbx), %rdi
movq %rdi, 0x18(%rsp)
movq %r15, %rsi
callq 0x4594
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x34ac
movq 0x4b97(%rip), %r15      # 0x7fd8
leaq 0x1e72(%rip), %rsi      # 0x52ba
movl $0x1, %edx
movq %r15, %rdi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r15
leaq 0x1e50(%rip), %rsi      # 0x52bc
movl $0x2c, %edx
movq %rax, %rdi
callq 0x2220
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x188(%rbx), %rdi
callq 0x2030
movb $0x0, 0x180(%rbx)
movq %r14, %rdi
callq 0x2150
leaq 0x90(%rbx), %r14
leaq 0x10(%rbx), %rax
movq %rax, 0x20(%rsp)
leaq 0xc0(%rbx), %rax
movq %rax, 0x10(%rsp)
movq 0x4afa(%rip), %r15      # 0x7fd8
leaq 0x1dd5(%rip), %rbp      # 0x52ba
leaq 0x1e66(%rip), %r13      # 0x5352
movl $0x1, %edx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r12
movl $0x24, %edx
movq %rax, %rdi
leaq 0x1dce(%rip), %rsi      # 0x52e9
callq 0x2220
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %r14, %rdi
callq 0x2290
movb $0x1, 0xb8(%rbx)
movl $0x1, %edx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r12
movl $0xb, %edx
movq %rax, %rdi
leaq 0x1d88(%rip), %rsi      # 0x530e
callq 0x2220
movq 0x58(%rbx), %rax
movq %rax, %rcx
subq 0x38(%rbx), %rcx
shrq $0x3, %rcx
cmpq $0x1, %rax
adcq $-0x1, %rcx
shlq $0x4, %rcx
movq 0x30(%rbx), %rsi
movq 0x40(%rbx), %rax
subq 0x48(%rbx), %rax
subq 0x20(%rbx), %rsi
sarq $0x5, %rax
sarq $0x5, %rsi
addq %rax, %rsi
addq %rcx, %rsi
movq %r12, %rdi
callq 0x2110
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %r13, %rsi
callq 0x2220
movzbl 0x150(%rbx), %esi
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
movq %r13, %rsi
callq 0x2220
movzbl 0x152(%rbx), %esi
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x20(%rbx), %rdi
cmpq %rdi, 0x40(%rbx)
sete %al
jne 0x3702
cmpb $0x1, 0x150(%rbx)
jne 0x3702
cmpb $0x0, 0x152(%rbx)
jne 0x3702
movl $0x1, %edx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r12
movl $0xb, %edx
movq %rax, %rdi
leaq 0x1c86(%rip), %rsi      # 0x531a
callq 0x2220
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x22b0
movl $0x1, %edx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r12
movl $0xd, %edx
movq %rax, %rdi
leaq 0x1c29(%rip), %rsi      # 0x5326
jmp 0x35da
cmpb $0x0, 0x150(%rbx)
je 0x3832
cmpb $0x1, 0x152(%rbx)
je 0x385e
testb $0x1, %al
jne 0x388a
movq $0x0, 0x28(%rsp)
movq (%rdi), %rax
testq %rax, %rax
je 0x3761
movq %rax, 0x28(%rsp)
testb $0x1, %al
jne 0x374d
addq $0x8, %rdi
leaq 0x30(%rsp), %rsi
xorl %edx, %edx
callq *(%rax)
jmp 0x3761
movq 0x18(%rdi), %rax
leaq 0x30(%rsp), %rcx
movq %rax, 0x10(%rcx)
movups 0x8(%rdi), %xmm0
movups %xmm0, (%rcx)
movq 0x20(%rsp), %rdi
callq 0x433c
movl $0x1, %edx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r12
movl $0x21, %edx
movq %rax, %rdi
leaq 0x1c63(%rip), %rsi      # 0x53fd
callq 0x2220
movq 0x58(%rbx), %rax
movq %rax, %rcx
subq 0x38(%rbx), %rcx
shrq $0x3, %rcx
cmpq $0x1, %rax
adcq $-0x1, %rcx
shlq $0x4, %rcx
movq 0x30(%rbx), %rsi
movq 0x40(%rbx), %rax
subq 0x48(%rbx), %rax
subq 0x20(%rbx), %rsi
sarq $0x5, %rax
sarq $0x5, %rsi
addq %rax, %rsi
addq %rcx, %rsi
movq %r12, %rdi
callq 0x2110
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movb $0x0, 0xb8(%rbx)
movq %r14, %rdi
callq 0x2150
leaq 0x28(%rsp), %rdi
callq 0x4366
leaq 0x28(%rsp), %rdi
callq 0x308a
jmp 0x34ec
movq 0x479f(%rip), %rdi      # 0x7fd8
leaq 0x1a7a(%rip), %rsi      # 0x52ba
callq 0x21d0
movq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x2060
leaq 0x1adb(%rip), %rsi      # 0x5334
jmp 0x39b9
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x38a9
leaq 0x1ae2(%rip), %rdi      # 0x5354
leaq 0x1afc(%rip), %rsi      # 0x5375
leaq 0x1b08(%rip), %rcx      # 0x5388
movl $0x58, %edx
callq 0x2100
leaq 0x1b58(%rip), %rdi      # 0x53e9
leaq 0x1add(%rip), %rsi      # 0x5375
leaq 0x1ae9(%rip), %rcx      # 0x5388
movl $0x66, %edx
callq 0x2100
leaq 0x8(%rsp), %rsi
movq 0x18(%rsp), %r15
movq %r15, %rdi
callq 0x46a6
movq %r15, %rdi
movq %rax, %rsi
callq 0x4722
movq 0x10(%rsp), %rdi
callq 0x2030
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x3992
movb $0x0, 0x152(%rbx)
movq 0x46e9(%rip), %r15      # 0x7fd8
leaq 0x19c4(%rip), %rsi      # 0x52ba
movl $0x1, %edx
movq %r15, %rdi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r15
leaq 0x1a91(%rip), %rsi      # 0x53ab
movl $0x1c, %edx
movq %rax, %rdi
callq 0x2220
movq 0x88(%rbx), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r15
leaq 0x1a12(%rip), %rsi      # 0x5352
movl $0x1, %edx
movq %rax, %rdi
callq 0x2220
movzbl 0x152(%rbx), %esi
movq %r15, %rdi
callq 0x22f0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21c0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1e8(%rbx), %rdi
callq 0x2030
movq 0x463f(%rip), %rdi      # 0x7fd8
leaq 0x191a(%rip), %rsi      # 0x52ba
callq 0x21d0
movq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x2060
leaq 0x1a0f(%rip), %rsi      # 0x53c8
movq %rax, %rdi
callq 0x21d0
movq 0x88(%rbx), %rsi
movq %rax, %rdi
callq 0x2060
movq %rax, %rdi
callq 0x20b0
movq %r14, %rdi
callq 0x4332
xorl %edi, %edi
callq 0x2330
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x308a
movq %rbx, %rdi
callq 0x2320