Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Fix cross-process access in MC_request_is_enabled() for SIMCALL_MUTEX_LOCK
[simgrid.git] / src / mc / mc_base.c
index 82ca8c6..b380bb3 100644 (file)
@@ -4,19 +4,31 @@
 /* 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. */
 
+#include <assert.h>
+
 #include <simgrid/simix.h>
 
 #include "mc_base.h"
 #include "../simix/smx_private.h"
 #include "mc_record.h"
 
+#ifdef HAVE_MC
+#include "mc_process.h"
+#include "mc_model_checker.h"
+#include "mc_protocol.h"
+#include "mc_smx.h"
+#include "mc_server.h"
+#endif
+
 XBT_LOG_NEW_CATEGORY(mc, "All MC categories");
 
-/**
- * \brief Schedules all the process that are ready to run
- */
 void MC_wait_for_requests(void)
 {
+  if (mc_mode == MC_MODE_SERVER) {
+    MC_server_wait_client(&mc_model_checker->process);
+    return;
+  }
+
   smx_process_t process;
   smx_simcall_t req;
   unsigned int iter;
@@ -35,6 +47,9 @@ int MC_request_is_enabled(smx_simcall_t req)
 {
   unsigned int index = 0;
   smx_synchro_t act = 0;
+#ifdef HAVE_MC
+  s_smx_synchro_t temp_synchro;
+#endif
 
   switch (req->call) {
   case SIMCALL_NONE:
@@ -43,6 +58,17 @@ int MC_request_is_enabled(smx_simcall_t req)
   case SIMCALL_COMM_WAIT:
     /* FIXME: check also that src and dst processes are not suspended */
     act = simcall_comm_wait__get__comm(req);
+
+#ifdef HAVE_MC
+    // Fetch from MCed memory:
+    if (!MC_process_is_self(&mc_model_checker->process)) {
+      MC_process_read(&mc_model_checker->process, MC_PROCESS_NO_FLAG,
+        &temp_synchro, act, sizeof(temp_synchro),
+        MC_PROCESS_INDEX_ANY);
+      act = &temp_synchro;
+    }
+#endif
+
     if (simcall_comm_wait__get__timeout(req) >= 0) {
       /* If it has a timeout it will be always be enabled, because even if the
        * communication is not ready, it can timeout and won't block. */
@@ -56,12 +82,65 @@ int MC_request_is_enabled(smx_simcall_t req)
     }
     return (act->comm.src_proc && act->comm.dst_proc);
 
-  case SIMCALL_COMM_WAITANY:
-    /* Check if it has at least one communication ready */
-    xbt_dynar_foreach(simcall_comm_waitany__get__comms(req), index, act)
+  case SIMCALL_COMM_WAITANY: {
+#ifdef HAVE_MC
+    // Read dynar:
+    s_xbt_dynar_t comms;
+    MC_process_read_simple(&mc_model_checker->process,
+      &comms, simcall_comm_waitany__get__comms(req), sizeof(comms));
+    // Read dynar buffer:
+    assert(comms.elmsize == sizeof(act));
+    size_t buffer_size = comms.elmsize * comms.used;
+    char buffer[buffer_size];
+    MC_process_read_simple(&mc_model_checker->process,
+      buffer, comms.data, sizeof(buffer));
+#endif
+
+#ifdef HAVE_MC
+    for (index = 0; index < comms.used; ++index) {
+      memcpy(&act, buffer + comms.elmsize * index, sizeof(act));
+#else
+    xbt_dynar_foreach(simcall_comm_waitany__get__comms(req), index, act) {
+#endif
+
+#ifdef HAVE_MC
+      // Fetch from MCed memory:
+      if (!MC_process_is_self(&mc_model_checker->process)) {
+        MC_process_read(&mc_model_checker->process, MC_PROCESS_NO_FLAG,
+          &temp_synchro, act, sizeof(temp_synchro),
+          MC_PROCESS_INDEX_ANY);
+        act = &temp_synchro;
+      }
+#endif
+
       if (act->comm.src_proc && act->comm.dst_proc)
         return TRUE;
+    }
     return FALSE;
+  }
+
+  case SIMCALL_MUTEX_LOCK: {
+    smx_mutex_t mutex = simcall_mutex_lock__get__mutex(req);
+#ifdef HAVE_MC
+    s_smx_mutex_t temp_mutex;
+    if (!MC_process_is_self(&mc_model_checker->process)) {
+      MC_process_read(&mc_model_checker->process, MC_PROCESS_NO_FLAG,
+        &temp_mutex, mutex, sizeof(temp_mutex),
+        MC_PROCESS_INDEX_ANY);
+      mutex = &temp_mutex;
+    }
+#endif
+    if(mutex->owner == NULL)
+      return TRUE;
+    else
+#ifdef HAVE_MC
+      // TODO, *(mutex->owner) :/
+      return MC_smx_resolve_process(mutex->owner)->pid ==
+        MC_smx_resolve_process(req->issuer)->pid;
+#else
+      return mutex->owner->pid == req->issuer->pid;
+#endif
+    }
 
   default:
     /* The rest of the requests are always enabled */
@@ -78,6 +157,7 @@ int MC_request_is_visible(smx_simcall_t req)
       || req->call == SIMCALL_COMM_TEST
       || req->call == SIMCALL_COMM_TESTANY
       || req->call == SIMCALL_MC_RANDOM
+      || req->call == SIMCALL_MUTEX_LOCK
 #ifdef HAVE_MC
       || req->call == SIMCALL_MC_SNAPSHOT
       || req->call == SIMCALL_MC_COMPARE_SNAPSHOTS