// File: /workspace/github_cpp_makefile_star2_O3/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
movq %rax, %r14
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
movq 0x4c18(%rip), %r12      # 0x7fd8
leaq 0x1edf(%rip), %rsi      # 0x52a6
movl $0x13, %edx
movq %r12, %rdi
callq 0x2220
movq %r12, %rdi
movq %r14, %rsi
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 0x45a4
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x34af
movq 0x4b94(%rip), %r15      # 0x7fd8
leaq 0x1e6f(%rip), %rsi      # 0x52ba
movl $0x1, %edx
movq %r15, %rdi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r15
leaq 0x1e4d(%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 0x4af7(%rip), %r15      # 0x7fd8
leaq 0x1dd2(%rip), %rbp      # 0x52ba
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 0x1dd2(%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 0x1d8c(%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
leaq 0x1d78(%rip), %r13      # 0x5352
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)
je 0x36a1
xorl %r13d, %r13d
cmpb $0x0, 0x150(%rbx)
je 0x38a9
cmpb $0x1, 0x152(%rbx)
je 0x38d5
testb %r13b, %r13b
jne 0x3901
movq $0x0, 0x28(%rsp)
movq (%rdi), %rax
testq %rax, %rax
je 0x37d8
movq %rax, 0x28(%rsp)
addq $0x8, %rdi
testb $0x1, %al
jne 0x37c5
leaq 0x30(%rsp), %rsi
xorl %edx, %edx
callq *(%rax)
jmp 0x37d8
movb $0x1, %r13b
cmpb $0x1, 0x150(%rbx)
jne 0x364a
cmpb $0x0, 0x152(%rbx)
jne 0x364a
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 0x1c35(%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 0x1bd8(%rip), %rsi      # 0x5326
callq 0x2220
movzbl 0x150(%rbx), %esi
movq %r12, %rdi
callq 0x22f0
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1bde(%rip), %rsi      # 0x5352
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)
je 0x36a4
jmp 0x3647
movq 0x10(%rdi), %rax
leaq 0x30(%rsp), %rcx
movq %rax, 0x10(%rcx)
movups (%rdi), %xmm0
movups %xmm0, (%rcx)
movq 0x20(%rsp), %rdi
callq 0x4350
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 0x1bec(%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 0x437a
leaq 0x28(%rsp), %rdi
callq 0x308a
jmp 0x34e8
movq 0x4728(%rip), %rdi      # 0x7fd8
leaq 0x1a03(%rip), %rsi      # 0x52ba
callq 0x21d0
movq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x2060
leaq 0x1a64(%rip), %rsi      # 0x5334
jmp 0x3a30
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x3920
leaq 0x1a6b(%rip), %rdi      # 0x5354
leaq 0x1a85(%rip), %rsi      # 0x5375
leaq 0x1a91(%rip), %rcx      # 0x5388
movl $0x58, %edx
callq 0x2100
leaq 0x1ae1(%rip), %rdi      # 0x53e9
leaq 0x1a66(%rip), %rsi      # 0x5375
leaq 0x1a72(%rip), %rcx      # 0x5388
movl $0x66, %edx
callq 0x2100
leaq 0x8(%rsp), %rsi
movq 0x18(%rsp), %r15
movq %r15, %rdi
callq 0x46b6
movq %r15, %rdi
movq %rax, %rsi
callq 0x4738
movq 0x10(%rsp), %rdi
callq 0x2030
movq 0x88(%rbx), %rax
cmpq 0x8(%rbx), %rax
jne 0x3a09
movb $0x0, 0x152(%rbx)
movq 0x4672(%rip), %r15      # 0x7fd8
leaq 0x194d(%rip), %rsi      # 0x52ba
movl $0x1, %edx
movq %r15, %rdi
callq 0x2220
movq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r15
leaq 0x1a1a(%rip), %rsi      # 0x53ab
movl $0x1c, %edx
movq %rax, %rdi
callq 0x2220
movq 0x88(%rbx), %rsi
movq %r15, %rdi
callq 0x2110
movq %rax, %r15
leaq 0x199b(%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 0x45c8(%rip), %rdi      # 0x7fd8
leaq 0x18a3(%rip), %rsi      # 0x52ba
callq 0x21d0
movq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x2060
leaq 0x1998(%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 0x4346
xorl %edi, %edi
callq 0x2330
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x308a
movq %rbx, %rdi
callq 0x2320
nop