#include "xbt/sysdep.h"
#include "xbt/log.h"
#include "xbt/dict.h"
-#include "msg/mailbox.h"
#include "mc/mc.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix,
}
/**
- * \brief Move a process to the list of processes to destroy.
+ * \brief Returns whether a process has pending asynchronous communications.
+ * \return true if there are asynchronous communications in this process
+ */
+int SIMIX_process_has_pending_comms(smx_process_t process) {
+
+ return xbt_fifo_size(process->comms) > 0;
+}
+
+/**
+ * \brief Moves a process to the list of processes to destroy.
*/
void SIMIX_process_cleanup(smx_process_t process)
{
smx_action_t action;
while ((action = xbt_fifo_pop(process->comms))) {
- /* make sure no one will finish the comm after this process is destroyed */
+ /* make sure no one will finish the comm after this process is destroyed,
+ * because src_proc or dst_proc would be an invalid pointer */
SIMIX_comm_cancel(action);
if (action->comm.src_proc == process) {
if (action->comm.detached) {
if (action->comm.refcount == 0) {
+ XBT_DEBUG("Increase the refcount before destroying it since it's detached");
/* I'm not supposed to destroy a detached comm from the sender side,
* unless there is no receiver matching the rdv */
action->comm.refcount++;
SIMIX_comm_destroy(action);
}
- }
- else {
+ else {
+ XBT_DEBUG("Don't destroy it since its refcount is %d", action->comm.refcount);
+ }
+ } else {
SIMIX_comm_destroy(action);
}
}
(*process)->smx_host = host;
(*process)->data = data;
(*process)->comms = xbt_fifo_new();
+ (*process)->request.issuer = *process;
XBT_VERB("Create context %s", (*process)->name);
(*process)->context = SIMIX_context_new(code, argc, argv,
break;
case SIMIX_ACTION_COMMUNICATE:
+ xbt_fifo_remove(process->comms, process->waiting_action);
SIMIX_comm_destroy(process->waiting_action);
break;
return xbt_swag_size(simix_global->process_list);
}
-void* SIMIX_process_self_get_data(void)
+void* SIMIX_process_self_get_data(smx_process_t self)
{
- smx_process_t me = SIMIX_process_self();
- if (!me) {
+ xbt_assert(self == SIMIX_process_self(), "This is not the current process");
+
+ if (!self) {
return NULL;
}
- return SIMIX_process_get_data(me);
+ return SIMIX_process_get_data(self);
}
-void SIMIX_process_self_set_data(void *data)
+void SIMIX_process_self_set_data(smx_process_t self, void *data)
{
- SIMIX_process_set_data(SIMIX_process_self(), data);
+ xbt_assert(self == SIMIX_process_self(), "This is not the current process");
+
+ SIMIX_process_set_data(self, data);
}
void* SIMIX_process_get_data(smx_process_t process)
}
/**
- * Calling this function makes the process to yield.
- * Only the processes can call this function, giving back the control to maestro
+ * \brief Calling this function makes the process to yield.
+ *
+ * Only the current process can call this function, giving back the control to
+ * maestro.
+ *
+ * \param self the current process
*/
-void SIMIX_process_yield(void)
+void SIMIX_process_yield(smx_process_t self)
{
- smx_process_t self = SIMIX_process_self();
-
XBT_DEBUG("Yield process '%s'", self->name);
/* Go into sleep and return control to maestro */
void SIMIX_process_set_context(smx_process_t p,smx_context_t c) {
p->context = c;
}
+
+/**
+ * \brief Returns the list of processes to run.
+ */
+xbt_dynar_t SIMIX_process_get_runnable(void)
+{
+ return simix_global->process_to_run;
+}