/** * \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(); }
/** @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(); }
/** * \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(); }
/** 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(); }
/** @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(); }
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; }
/** * \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(); }