X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/4184211ef3d1957a395a461e4ca480a7928e83a8..f875edb3c8ebff56ebfb9341d198bdf498a51618:/src/mc/mc_base.c diff --git a/src/mc/mc_base.c b/src/mc/mc_base.c index 82ca8c6a4f..b380bb3b16 100644 --- a/src/mc/mc_base.c +++ b/src/mc/mc_base.c @@ -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 + #include #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