예제 #1
0
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;
}
예제 #2
0
파일: Mutex.cpp 프로젝트: 0664j35t3r/sweb
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;
}
예제 #3
0
파일: Lock.cpp 프로젝트: 0664j35t3r/sweb
void Lock::doChecksBeforeWaiting()
{
  // Check if the interrupts are set. Else, we maybe wait forever
  checkInterrupts("Lock::doChecksBeforeWaiting");
  // Check if the thread has been waken up even if he is already waiting on another lock.
  checkCurrentThreadStillWaitingOnAnotherLock();
  // Check if locking this lock would result in a deadlock.
  checkForDeadLock();
}
예제 #4
0
void Condition::wait(bool re_acquire_mutex, pointer called_by)
{
  if(unlikely(system_state != RUNNING))
    return;
  if(!called_by)
    called_by = getCalledBefore(1);
//  debug(LOCK, "Condition::wait: Thread %s (%p) is waiting on condition %s (%p).\n",
//        currentThread->getName(), currentThread, getName(), this);
//  if(kernel_debug_info)
//  {
//    debug(LOCK, "The wait is called by: ");
//    kernel_debug_info->printCallInformation(called_by);
//  }

  assert(mutex_->isHeldBy(currentThread));
  // check if the interrupts are enabled and the thread is not waiting for some other locks
  checkInterrupts("Condition::wait");
  checkCurrentThreadStillWaitingOnAnotherLock();

  assert(currentThread->holding_lock_list_);
  if(currentThread->holding_lock_list_->hasNextOnHoldingList())
  {
    debug(LOCK, "Condition::wait: Warning: The thread %s (%p) is holding some locks when going to sleep on condition %s (%p).\n"
          "This may lower the performance of the system, and cause undetectable deadlocks!\n",
          currentThread->getName(), currentThread, getName(), this);
    printHoldingList(currentThread);
  }
  lockWaitersList();
  last_accessed_at_ = called_by;
  // The mutex can be released here, because for waking up another thread, the list lock is needed, which is still held by the thread.
  mutex_->release(called_by);
  Scheduler::instance()->sleepAndRelease(*(Lock*)this);
  if(re_acquire_mutex)
  {
    assert(mutex_);
    mutex_->acquire(called_by);
  }
}