void Mutex::acquire(pointer called_by) { if(unlikely(system_state != RUNNING)) return; if(!called_by) called_by = getCalledBefore(1); // debug(LOCK, "Mutex::acquire: Mutex: %s (%p), currentThread: %s (%p).\n", // getName(), this, currentThread->getName(), currentThread); // if(kernel_debug_info) // { // debug(LOCK, "The acquire is called by: "); // kernel_debug_info->printCallInformation(called_by); // } while(ArchThreads::testSetLock(mutex_, 1)) { checkCurrentThreadStillWaitingOnAnotherLock(); lockWaitersList(); // Here we have to check for the lock again, in case some one released it in between, we might sleep forever. if(!ArchThreads::testSetLock(mutex_, 1)) { unlockWaitersList(); break; } // check for deadlocks, interrupts... doChecksBeforeWaiting(); Scheduler::instance()->sleepAndRelease(*(Lock*)this); // We have been waken up again. currentThread->lock_waiting_on_ = 0; } assert(held_by_ == 0); pushFrontToCurrentThreadHoldingList(); last_accessed_at_ = called_by; held_by_ = currentThread; }
void Mutex::acquire(const char* debug_info) { if(unlikely(system_state != RUNNING)) return; //debug(LOCK, "Mutex::acquire: Mutex: %s (%p), currentThread: %s (%p).\n", // getName(), this, currentThread->getName(), currentThread); while(ArchThreads::testSetLock(mutex_, 1)) { checkCurrentThreadStillWaitingOnAnotherLock(debug_info); lockWaitersList(); // Here we have to check for the lock again, in case some one released it in between, we might sleep forever. if(!ArchThreads::testSetLock(mutex_, 1)) { unlockWaitersList(); break; } // check for deadlocks, interrupts... doChecksBeforeWaiting(debug_info); Scheduler::instance()->sleepAndRelease(*(Lock*)this); // We have been waken up again. currentThread->lock_waiting_on_ = 0; } assert(held_by_ == 0); pushFrontToCurrentThreadHoldingList(); held_by_ = currentThread; }
bool Mutex::acquireNonBlocking(pointer called_by) { if(unlikely(system_state != RUNNING)) return true; if(!called_by) called_by = getCalledBefore(1); // debug(LOCK, "Mutex::acquireNonBlocking: Mutex: %s (%p), currentThread: %s (%p).\n", // getName(), this, currentThread->getName(), currentThread); // if(kernel_debug_info) // { // debug(LOCK, "The acquire is called by: "); // kernel_debug_info->printCallInformation(called_by); // } // There may be some cases where the pre-checks may not be wished here. // But these cases are usually dirty implemented, and it would not be necessary to call this method there. // So in case you see this comment, re-think your implementation and don't just comment out this line! doChecksBeforeWaiting(); if(ArchThreads::testSetLock(mutex_, 1)) { // The mutex is already held by another thread, // so we are not allowed to lock it. return false; } assert(held_by_ == 0); last_accessed_at_ = called_by; held_by_ = currentThread; pushFrontToCurrentThreadHoldingList(); return true; }