//if we modify the swag between calls, normal version may loop forever //this safe version ensures that we browse the swag elements only once lmm_variable_t lmm_get_var_from_cnst_safe(lmm_system_t /*sys*/, lmm_constraint_t cnst, lmm_element_t * elem, lmm_element_t * nextelem, int * numelem) { if (!(*elem)){ *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->enabled_element_set)); *numelem = xbt_swag_size(&(cnst->enabled_element_set))+xbt_swag_size(&(cnst->disabled_element_set))-1; if (!(*elem)) *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->disabled_element_set)); }else{ *elem = *nextelem; if(*numelem>0){ (*numelem) --; }else return NULL; } if (*elem){ //elem is not null, so we carry on if(xbt_swag_belongs(*elem,&(cnst->enabled_element_set))){ //Look at enabled_element_set, and jump to disabled_element_set when finished *nextelem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->enabled_element_set.offset); if (!(*nextelem)) *nextelem = (lmm_element_t) xbt_swag_getFirst(&(cnst->disabled_element_set)); } else { *nextelem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->disabled_element_set.offset); } return (*elem)->variable; }else return NULL; }
/* @brief Remove a constraint * Currently this is dead code, but it is exposed in maxmin.h * Apparently, this call was designed assuming that constraint would no more have elements in it. * If not the case, assertion will fail, and you need to add calls e.g. to lmm_shrink before effectively removing it. */ inline void lmm_constraint_free(lmm_system_t sys,lmm_constraint_t cnst) { xbt_assert(!xbt_swag_size(&(cnst->active_element_set)),"Removing constraint but it still has active elements"); xbt_assert(!xbt_swag_size(&(cnst->enabled_element_set)),"Removing constraint but it still has enabled elements"); xbt_assert(!xbt_swag_size(&(cnst->disabled_element_set)),"Removing constraint but it still has disabled elements"); remove_constraint(sys, cnst); lmm_cnst_free(sys, cnst); }
/* * \brief Destroys a host (internal call only) */ void __MSG_host_destroy(msg_host_priv_t host) { #ifdef MSG_USE_DEPRECATED if (msg_global->max_channel > 0) free(host->mailboxes); #endif if (xbt_swag_size(host->vms) > 0 ) { XBT_VERB("Host shut down, but it still hosts %d VMs. They will be leaked.",xbt_swag_size(host->vms)); } xbt_swag_free(host->vms); free(host); }
void lmm_shrink(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var) { lmm_element_t elem = NULL; int found = 0; int i; for (i = 0; i < var->cnsts_number; i++) { elem = &(var->cnsts[i]); if (elem->constraint == cnst) { found = 1; break; } } if (!found) { XBT_DEBUG("cnst %p is not found in var %p", cnst, var); return; } sys->modified = 1; XBT_DEBUG("remove elem(value %f, cnst %p, var %p) in var %p", elem->value, elem->constraint, elem->variable, var); /* We are going to change the constraint object and the variable object. * Propagate this change to other objects. Calling here before removing variable from not active elements * (inactive elements are not visited) */ lmm_update_modified_set(sys, cnst); //Useful in case var was already removed from the constraint lmm_update_modified_set(sys, var->cnsts[0].constraint); // will look up enabled_element_set of this constraint, and //then each var in the enabled_element_set, and each var->cnsts[i]. if(xbt_swag_remove(elem, &(elem->constraint->enabled_element_set))) lmm_decrease_concurrency(elem); xbt_swag_remove(elem, &(elem->constraint->active_element_set)); elem->constraint = NULL; elem->variable = NULL; elem->value = 0; var->cnsts_number -= 1; //No variable in this constraint -> make it inactive if (xbt_swag_size(&(cnst->enabled_element_set))+xbt_swag_size(&(cnst->disabled_element_set)) == 0) make_constraint_inactive(sys, cnst); else { //Check maxconcurrency to see if we can enable new variables lmm_on_disabled_var(sys,elem->constraint); } lmm_check_concurrency(sys); }
/** 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(); }
static XBT_INLINE void lmm_variable_disable(lmm_system_t sys, lmm_variable_t var) { int i; int n; lmm_element_t elem = NULL; XBT_IN("(sys=%p, var=%p)", sys, var); sys->modified = 1; n = 0; for (i = 0; i < var->cnsts_number; i++) { elem = &var->cnsts[i]; xbt_swag_remove(elem, &(elem->constraint->element_set)); xbt_swag_remove(elem, &(elem->constraint->active_element_set)); if (!xbt_swag_size(&(elem->constraint->element_set))) make_constraint_inactive(sys, elem->constraint); else { if (n < i) var->cnsts[n].constraint = elem->constraint; n++; } } if (n) { var->cnsts_number = n; lmm_update_modified_set(sys, var->cnsts[0].constraint); } var->cnsts_number = 0; XBT_OUT(); }
static inline void lmm_variable_remove(lmm_system_t sys, lmm_variable_t var) { int i; int nelements; lmm_element_t elem = NULL; XBT_IN("(sys=%p, var=%p)", sys, var); sys->modified = 1; //TODOLATER Can do better than that by leaving only the variable in only one enabled_element_set, call //lmm_update_modified_set, and then remove it.. if(var->cnsts_number) lmm_update_modified_set(sys, var->cnsts[0].constraint); for (i = 0; i < var->cnsts_number; i++) { elem = &var->cnsts[i]; if(var->weight>0) lmm_decrease_concurrency(elem); xbt_swag_remove(elem, &(elem->constraint->enabled_element_set)); xbt_swag_remove(elem, &(elem->constraint->disabled_element_set)); xbt_swag_remove(elem, &(elem->constraint->active_element_set)); nelements=xbt_swag_size(&(elem->constraint->enabled_element_set)) + xbt_swag_size(&(elem->constraint->disabled_element_set)); if (!nelements) make_constraint_inactive(sys, elem->constraint); else lmm_on_disabled_var(sys,elem->constraint); } //Check if we can enable new variables going through the constraints where var was. //Do it after removing all elements, so he first disabled variables get priority over those with smaller requirement for (i = 0; i < var->cnsts_number; i++) { elem = &var->cnsts[i]; if(xbt_swag_size(&(elem->constraint->disabled_element_set))) lmm_on_disabled_var(sys,elem->constraint); } var->cnsts_number = 0; lmm_check_concurrency(sys); XBT_OUT(); }
void lmm_shrink(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var) { lmm_element_t elem = NULL; int found = 0; int i; for (i = 0; i < var->cnsts_number; i++) { elem = &(var->cnsts[i]); if (elem->constraint == cnst) { found = 1; break; } } if (!found) { XBT_DEBUG("cnst %p is not found in var %p", cnst, var); return; } sys->modified = 1; XBT_DEBUG("remove elem(value %f, cnst %p, var %p) in var %p", elem->value, elem->constraint, elem->variable, var); /* We are going to change the constraint object and the variable object. * Propagate this change to other objects. Calling here (not after * modification) is correct? */ lmm_update_modified_set(sys, cnst); lmm_update_modified_set(sys, var->cnsts[0].constraint); // will look up element_set of this constraint, and then each var in the element_set, and each var->cnsts[i]. /* now var->cnsts[i] is not necessary any more */ xbt_swag_remove(elem, &(elem->constraint->element_set)); xbt_swag_remove(elem, &(elem->constraint->active_element_set)); elem->constraint = NULL; elem->variable = NULL; elem->value = 0; /* We do not want to have an empty element entry before the last entry. So, * plug up the hole with the last one. */ if (i < var->cnsts_number - 1) renew_elem_entry(&var->cnsts[i], &var->cnsts[var->cnsts_number - 1]); var->cnsts_number -= 1; if (xbt_swag_size(&(cnst->element_set)) == 0) make_constraint_inactive(sys, cnst); }
void intrusive_ptr_release(s_smx_cond_t *cond) { auto count = --(cond->refcount_); if (count == 0) { xbt_assert(xbt_swag_size(cond->sleeping) == 0, "Cannot destroy conditional since someone is still using it"); xbt_swag_free(cond->sleeping); delete cond; } }
/** * \brief Broadcasts a condition. * * Signal ALL processes waiting on a condition. * If there are no process waiting, no action is done. * \param cond A condition */ void SIMIX_cond_broadcast(smx_cond_t cond) { XBT_IN("(%p)",cond); XBT_DEBUG("Broadcast condition %p", cond); /* Signal the condition until nobody is waiting on it */ while (xbt_swag_size(cond->sleeping)) { SIMIX_cond_signal(cond); } XBT_OUT(); }
/** @brief Destroys a semaphore */ void SIMIX_sem_destroy(smx_sem_t sem) { XBT_IN("(%p)",sem); XBT_DEBUG("Destroy semaphore %p", sem); if (sem != NULL) { xbt_assert(xbt_swag_size(sem->sleeping) == 0, "Cannot destroy semaphore since someone is still using it"); xbt_swag_free(sem->sleeping); xbt_free(sem); } XBT_OUT(); }
static mc_visited_state_t visited_state_new(){ mc_visited_state_t new_state = NULL; new_state = xbt_new0(s_mc_visited_state_t, 1); new_state->heap_bytes_used = mmalloc_get_bytes_used(std_heap); new_state->nb_processes = xbt_swag_size(simix_global->process_list); new_state->system_state = MC_take_snapshot(); new_state->num = mc_stats->expanded_states; return new_state; }
/** @brief Power off a VM. * * All hosted processes will be killed, but the VM state is preserved on memory. * It can later be restarted. * * @param issuer the actor requesting the shutdown */ void VirtualMachineImpl::shutdown(smx_actor_t issuer) { if (getState() != SURF_VM_STATE_RUNNING) THROWF(vm_error, 0, "Cannot shutdown VM %s: it is not running", piface_->cname()); xbt_swag_t process_list = piface_->extension<simgrid::simix::Host>()->process_list; XBT_DEBUG("shutdown VM %s, that contains %d processes", piface_->cname(), xbt_swag_size(process_list)); smx_actor_t smx_process, smx_process_safe; xbt_swag_foreach_safe(smx_process, smx_process_safe, process_list) { XBT_DEBUG("kill %s", smx_process->cname()); SIMIX_process_kill(smx_process, issuer); }
/** * \brief Destroys a contidion. * * Destroys and frees the condition's memory. * \param cond A condition */ void SIMIX_cond_destroy(smx_cond_t cond) { XBT_IN("(%p)",cond); XBT_DEBUG("Destroy condition %p", cond); if (cond != NULL) { xbt_assert(xbt_swag_size(cond->sleeping) == 0, "Cannot destroy conditional since someone is still using it"); xbt_swag_free(cond->sleeping); xbt_free(cond); } XBT_OUT(); }
void bottleneck_solve(lmm_system_t sys) { void *_var, *_var_next, *_cnst, *_cnst_next, *_elem; lmm_variable_t var = nullptr; lmm_constraint_t cnst = nullptr; s_lmm_constraint_t s_cnst; lmm_element_t elem = nullptr; xbt_swag_t cnst_list = nullptr; xbt_swag_t var_list = nullptr; xbt_swag_t elem_list = nullptr; int i; static s_xbt_swag_t cnst_to_update; if (!(sys->modified)) return; /* Init */ xbt_swag_init(&(cnst_to_update), xbt_swag_offset(s_cnst, saturated_constraint_set_hookup)); var_list = &(sys->variable_set); XBT_DEBUG("Variable set : %d", xbt_swag_size(var_list)); xbt_swag_foreach(_var, var_list) { var = (lmm_variable_t)_var; int nb = 0; var->value = 0.0; XBT_DEBUG("Handling variable %p", var); xbt_swag_insert(var, &(sys->saturated_variable_set)); for (i = 0; i < var->cnsts_number; i++) { if (var->cnsts[i].value == 0.0) nb++; } if ((nb == var->cnsts_number) && (var->weight > 0.0)) { XBT_DEBUG("Err, finally, there is no need to take care of variable %p", var); xbt_swag_remove(var, &(sys->saturated_variable_set)); var->value = 1.0; } if (var->weight <= 0.0) { XBT_DEBUG("Err, finally, there is no need to take care of variable %p", var); xbt_swag_remove(var, &(sys->saturated_variable_set)); } }
/** * \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(); }
if ((nb == var->cnsts_number) && (var->weight > 0.0)) { XBT_DEBUG("Err, finally, there is no need to take care of variable %p", var); xbt_swag_remove(var, &(sys->saturated_variable_set)); var->value = 1.0; } if (var->weight <= 0.0) { XBT_DEBUG("Err, finally, there is no need to take care of variable %p", var); xbt_swag_remove(var, &(sys->saturated_variable_set)); } } var_list = &(sys->saturated_variable_set); cnst_list = &(sys->active_constraint_set); XBT_DEBUG("Active constraints : %d", xbt_swag_size(cnst_list)); xbt_swag_foreach(_cnst, cnst_list) { cnst = (lmm_constraint_t)_cnst; xbt_swag_insert(cnst, &(sys->saturated_constraint_set)); } cnst_list = &(sys->saturated_constraint_set); xbt_swag_foreach(_cnst, cnst_list) { cnst = (lmm_constraint_t)_cnst; cnst->remaining = cnst->bound; cnst->usage = 0.0; } XBT_DEBUG("Fair bottleneck Initialized"); /* * Compute Usage and store the variables that reach the maximum.
/* xbt_test_assert(xbt_swag_remove(obj2, setB) == obj2); */ xbt_test_add("Traverse set A"); xbt_swag_foreach(obj, setA) { xbt_test_log("Saw: %s", obj->name); } xbt_test_add("Traverse set B"); xbt_swag_foreach(obj, setB) { xbt_test_log("Saw: %s", obj->name); } xbt_test_add("Ensure set content and length"); xbt_test_assert(xbt_swag_belongs(obj1, setA)); xbt_test_assert(xbt_swag_belongs(obj2, setA)); xbt_test_assert(!xbt_swag_belongs(obj1, setB)); xbt_test_assert(xbt_swag_belongs(obj2, setB)); xbt_test_assert(xbt_swag_size(setA) == 2); xbt_test_assert(xbt_swag_size(setB) == 1); xbt_swag_free(setA); xbt_swag_free(setB); xbt_free(obj1); xbt_free(obj2); } #endif /* SIMGRID_TEST */