예제 #1
0
/**
 * \brief Signalizes a condition.
 *
 * Signalizes a condition and wakes up a sleeping process. 
 * If there are no process sleeping, no action is done.
 * \param cond A condition
 */
void SIMIX_cond_signal(smx_cond_t cond)
{
  XBT_IN("(%p)",cond);
  smx_process_t proc = NULL;
  smx_mutex_t mutex = NULL;
  smx_simcall_t simcall = NULL;

  XBT_DEBUG("Signal condition %p", cond);

  /* If there are processes waiting for the condition choose one and try 
     to make it acquire the mutex */
  if ((proc = xbt_swag_extract(cond->sleeping))) {

    /* Destroy waiter's synchro action */
    SIMIX_synchro_destroy(proc->waiting_action);
    proc->waiting_action = NULL;

    /* Now transform the cond wait simcall into a mutex lock one */
    simcall = &proc->simcall;
    if(simcall->call == SIMCALL_COND_WAIT)
      mutex = simcall_cond_wait__get__mutex(simcall);
    else
      mutex = simcall_cond_wait_timeout__get__mutex(simcall);
    simcall->call = SIMCALL_MUTEX_LOCK;

    SIMIX_pre_mutex_lock(simcall, mutex);
  }
  XBT_OUT();
}
예제 #2
0
/** @brief release the semaphore
 *
 * Unlock a process waiting on the semaphore.
 * If no one was blocked, the semaphore capacity is increased by 1.
 */
void SIMIX_sem_release(smx_sem_t sem)
{
  XBT_IN("(%p)",sem);
  smx_process_t proc;

  XBT_DEBUG("Sem release semaphore %p", sem);
  if ((proc = xbt_swag_extract(sem->sleeping))) {
    proc = xbt_swag_extract(sem->sleeping);
    SIMIX_synchro_destroy(proc->waiting_action);
    proc->waiting_action = NULL;
    SIMIX_simcall_answer(&proc->simcall);
  } else if (sem->value < SMX_SEM_NOLIMIT) {
    sem->value++;
  }
  XBT_OUT();
}
예제 #3
0
/**
 * \brief Signalizes a condition.
 *
 * Signalizes a condition and wakes up a sleeping process. 
 * If there are no process sleeping, no action is done.
 * \param cond A condition
 */
void SIMIX_cond_signal(smx_cond_t cond)
{
  XBT_IN("(%p)",cond);
  smx_actor_t proc = nullptr;
  smx_mutex_t mutex = nullptr;
  smx_simcall_t simcall = nullptr;

  XBT_DEBUG("Signal condition %p", cond);

  /* If there are processes waiting for the condition choose one and try 
     to make it acquire the mutex */
  if ((proc = (smx_actor_t) xbt_swag_extract(cond->sleeping))) {

    /* Destroy waiter's synchronization */
    delete proc->waiting_synchro;
    proc->waiting_synchro = nullptr;

    /* Now transform the cond wait simcall into a mutex lock one */
    simcall = &proc->simcall;
    if(simcall->call == SIMCALL_COND_WAIT)
      mutex = simcall_cond_wait__get__mutex(simcall);
    else
      mutex = simcall_cond_wait_timeout__get__mutex(simcall);
    simcall->call = SIMCALL_MUTEX_LOCK;

    simcall_HANDLER_mutex_lock(simcall, mutex);
  }
  XBT_OUT();
}
예제 #4
0
/** Unlock a mutex for a process
 *
 * Unlocks the mutex and gives it to a process waiting for it. 
 * If the unlocker is not the owner of the mutex nothing happens.
 * If there are no process waiting, it sets the mutex as free.
 */
void Mutex::unlock(smx_actor_t issuer)
{
  XBT_IN("(%p, %p)", this, issuer);
  if(!this->locked)
    THROWF(mismatch_error, 0, "Cannot release that mutex: it was not locked.");

  /* If the mutex is not owned by the issuer, that's not good */
  if (issuer != this->owner)
    THROWF(mismatch_error, 0, "Cannot release that mutex: it was locked by %s (pid:%ld), not by you.",
        this->owner->name.c_str(),this->owner->pid);

  if (xbt_swag_size(this->sleeping) > 0) {
    /*process to wake up */
    smx_actor_t p = (smx_actor_t) xbt_swag_extract(this->sleeping);
    delete p->waiting_synchro;
    p->waiting_synchro = nullptr;
    this->owner = p;
    SIMIX_simcall_answer(&p->simcall);
  } else {
    /* nobody to wake up */
    this->locked = false;
    this->owner = nullptr;
  }
  XBT_OUT();
}
예제 #5
0
/** @brief release the semaphore
 *
 * Unlock a process waiting on the semaphore.
 * If no one was blocked, the semaphore capacity is increased by 1.
 */
void SIMIX_sem_release(smx_sem_t sem)
{
  XBT_IN("(%p)",sem);
  smx_actor_t proc;

  XBT_DEBUG("Sem release semaphore %p", sem);
  if ((proc = (smx_actor_t) xbt_swag_extract(sem->sleeping))) {
    delete proc->waiting_synchro;
    proc->waiting_synchro = nullptr;
    SIMIX_simcall_answer(&proc->simcall);
  } else if (sem->value < SMX_SEM_NOLIMIT) {
    sem->value++;
  }
  XBT_OUT();
}
예제 #6
0
파일: smx_smurf.c 프로젝트: sbadia/simgrid
smx_req_t SIMIX_request_pop(void)
{
  int i;
  smx_req_t req = NULL;
  int nthreads = SIMIX_context_get_nthreads();

  for(i=0; i < nthreads; i++){
    if((req = xbt_swag_extract(req_lists[i]))){
      XBT_DEBUG("Popped request %s (%d) of %s",
          SIMIX_request_name(req->issuer->request.call),
          req->issuer->request.call,
          req->issuer->name);
      return req;
    }
  }

  return NULL;
}
예제 #7
0
/**
 * \brief Unlocks a mutex.
 *
 * Unlocks the mutex and gives it to a process waiting for it. 
 * If the unlocker is not the owner of the mutex nothing happens.
 * If there are no process waiting, it sets the mutex as free.
 * \param mutex The mutex
 * \param issuer The process trying to unlock the mutex
 */
void SIMIX_mutex_unlock(smx_mutex_t mutex, smx_process_t issuer)
{
  XBT_IN("(%p, %p)",mutex,issuer);
  smx_process_t p;              /*process to wake up */

  /* If the mutex is not owned by the issuer do nothing */
  if (issuer != mutex->owner){
    XBT_OUT();
    return;
  }

  if (xbt_swag_size(mutex->sleeping) > 0) {
    p = xbt_swag_extract(mutex->sleeping);
    SIMIX_synchro_destroy(p->waiting_action);
    p->waiting_action = NULL;
    mutex->owner = p;
    SIMIX_simcall_answer(&p->simcall);
  } else {
    /* nobody to wake up */
    mutex->locked = 0;
    mutex->owner = NULL;
  }
  XBT_OUT();
}