Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
make sure that MSG_task_execute() is not called by error on parallel tasks
[simgrid.git] / src / msg / gos.c
index 267309b..54b4fa8 100644 (file)
@@ -1,8 +1,5 @@
-/*     $Id$      */
-
-/* Copyright (c) 2002-2007 Arnaud Legrand.                                  */
-/* Copyright (c) 2007 Bruno Donassolo.                                      */
-/* All rights reserved.                                                     */
+/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -42,20 +39,27 @@ MSG_error_t MSG_task_execute(m_task_t task)
   m_process_t self = MSG_process_self();
   e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM;
   CHECK_HOST();
+
+  simdata = task->simdata;
+
+  xbt_assert0(simdata->host_nb==0, "This is a parallel task. Go to hell.");
+
 #ifdef HAVE_TRACING
   TRACE_msg_task_execute_start (task);
 #endif
 
-  simdata = task->simdata;
 
   xbt_assert1((!simdata->compute) && (task->simdata->refcount == 1),
               "This task is executed somewhere else. Go fix your code! %d", task->simdata->refcount);
 
   DEBUG1("Computing on %s", MSG_process_self()->simdata->m_host->name);
 
-  if (simdata->comp_amount == 0)
+  if (simdata->computation_amount == 0) {
+#ifdef HAVE_TRACING
+    TRACE_msg_task_execute_end (task);
+#endif
     return MSG_OK;
-
+  }
   simdata->refcount++;
   SIMIX_mutex_lock(simdata->mutex);
   simdata->compute =
@@ -404,6 +408,93 @@ MSG_task_receive_ext(m_task_t * task, const char *alias, double timeout,
                                   timeout);
 }
 
+msg_comm_t MSG_task_isend(m_task_t task, const char *alias) {
+  simdata_task_t t_simdata = NULL;
+  m_process_t process = MSG_process_self();
+  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
+
+  CHECK_HOST();
+
+  /* FIXME: these functions are not tracable */
+
+  /* Prepare the task to send */
+  t_simdata = task->simdata;
+  t_simdata->sender = process;
+  t_simdata->source = MSG_host_self();
+
+  xbt_assert0(t_simdata->refcount == 1,
+              "This task is still being used somewhere else. You cannot send it now. Go fix your code!");
+
+  t_simdata->refcount++;
+  msg_global->sent_msg++;
+
+  process->simdata->waiting_task = task;
+
+  /* Send it by calling SIMIX network layer */
+
+  /* Kept for semantical compatibility with older implementation */
+  if(mailbox->cond)
+    SIMIX_cond_signal(mailbox->cond);
+
+  return SIMIX_network_isend(mailbox->rdv, t_simdata->message_size, t_simdata->rate,
+      task, sizeof(void*), &t_simdata->comm);
+}
+
+msg_comm_t MSG_task_irecv(m_task_t * task, const char *alias) {
+  smx_comm_t comm;
+  smx_rdv_t rdv = MSG_mailbox_get_by_alias(alias)->rdv;
+  msg_mailbox_t mailbox=MSG_mailbox_get_by_alias(alias);
+  size_t size = sizeof(void*);
+
+  CHECK_HOST();
+
+  /* FIXME: these functions are not tracable */
+
+  memset(&comm,0,sizeof(comm));
+
+  /* Kept for compatibility with older implementation */
+  xbt_assert1(!MSG_mailbox_get_cond(mailbox),
+              "A process is already blocked on this channel %s",
+              MSG_mailbox_get_alias(mailbox));
+
+  /* Sanity check */
+  xbt_assert0(task, "Null pointer for the task storage");
+
+  if (*task)
+    CRITICAL0("MSG_task_get() was asked to write in a non empty task struct.");
+
+  /* Try to receive it by calling SIMIX network layer */
+  return SIMIX_network_irecv(rdv, task, &size);
+}
+int MSG_comm_test(msg_comm_t comm) {
+  return SIMIX_network_test(comm);
+}
+MSG_error_t MSG_comm_wait(msg_comm_t comm,double timeout) {
+  xbt_ex_t e;
+  MSG_error_t res = MSG_OK;
+  TRY {
+    SIMIX_network_wait(comm,timeout);
+    //  (*task)->simdata->refcount--;
+
+    /* FIXME: these functions are not tracable */
+  }  CATCH(e){
+      switch(e.category){
+        case host_error:
+          res = MSG_HOST_FAILURE;
+          break;
+        case network_error:
+          res = MSG_TRANSFER_FAILURE;
+          break;
+        case timeout_error:
+          res = MSG_TIMEOUT;
+          break;
+        default:
+          xbt_die(bprintf("Unhandled SIMIX network exception: %s",e.msg));
+      }
+      xbt_ex_free(e);
+    }
+  return res;
+}
 
 /** \ingroup msg_gos_functions
  * \brief Put a task on a channel of an host and waits for the end of the