bool ModelChecker::handle_message(char* buffer, ssize_t size)
{
- s_mc_message_t base_message;
+ mc_message_t base_message;
if (size < (ssize_t) sizeof(base_message))
xbt_die("Broken message");
memcpy(&base_message, buffer, sizeof(base_message));
case MC_MESSAGE_IGNORE_HEAP:
{
- s_mc_ignore_heap_message_t message;
- if (size != sizeof(message))
- xbt_die("Broken messsage");
- memcpy(&message, buffer, sizeof(message));
-
- IgnoredHeapRegion region;
- region.block = message.block;
- region.fragment = message.fragment;
- region.address = message.address;
- region.size = message.size;
- process().ignore_heap(region);
- break;
+ s_mc_message_ignore_heap_t message;
+ if (size != sizeof(message))
+ xbt_die("Broken messsage");
+ memcpy(&message, buffer, sizeof(message));
+
+ IgnoredHeapRegion region;
+ region.block = message.block;
+ region.fragment = message.fragment;
+ region.address = message.address;
+ region.size = message.size;
+ process().ignore_heap(region);
+ break;
}
case MC_MESSAGE_UNIGNORE_HEAP:
{
- s_mc_ignore_memory_message_t message;
- if (size != sizeof(message))
- xbt_die("Broken messsage");
- memcpy(&message, buffer, sizeof(message));
- process().unignore_heap(
- (void *)(std::uintptr_t) message.addr, message.size);
- break;
+ s_mc_message_ignore_memory_t message;
+ if (size != sizeof(message))
+ xbt_die("Broken messsage");
+ memcpy(&message, buffer, sizeof(message));
+ process().unignore_heap((void*)(std::uintptr_t)message.addr, message.size);
+ break;
}
case MC_MESSAGE_IGNORE_MEMORY:
{
- s_mc_ignore_memory_message_t message;
- if (size != sizeof(message))
- xbt_die("Broken messsage");
- memcpy(&message, buffer, sizeof(message));
- this->process().ignore_region(message.addr, message.size);
- break;
+ s_mc_message_ignore_memory_t message;
+ if (size != sizeof(message))
+ xbt_die("Broken messsage");
+ memcpy(&message, buffer, sizeof(message));
+ this->process().ignore_region(message.addr, message.size);
+ break;
}
case MC_MESSAGE_STACK_REGION:
{
- s_mc_stack_region_message_t message;
- if (size != sizeof(message))
- xbt_die("Broken messsage");
- memcpy(&message, buffer, sizeof(message));
- this->process().stack_areas().push_back(message.stack_region);
+ s_mc_message_stack_region_t message;
+ if (size != sizeof(message))
+ xbt_die("Broken messsage");
+ memcpy(&message, buffer, sizeof(message));
+ this->process().stack_areas().push_back(message.stack_region);
}
break;
void ModelChecker::handle_simcall(Transition const& transition)
{
- s_mc_simcall_handle_message m;
+ s_mc_message_simcall_handle m;
memset(&m, 0, sizeof(m));
m.type = MC_MESSAGE_SIMCALL_HANDLE;
m.pid = transition.pid;
int res;
if ((res = this->process().getChannel().send(MC_MESSAGE_DEADLOCK_CHECK)))
xbt_die("Could not check deadlock state");
- s_mc_int_message_t message;
+ mc_message_int_t message;
ssize_t s = mc_model_checker->process().getChannel().receive(message);
if (s == -1)
xbt_die("Could not receive message");
// TODO, send a message to implement this in the MCed process
if(snapshot->privatization_index >= 0) {
// Fix the privatization mmap:
- s_mc_restore_message message;
+ s_mc_message_restore message;
message.type = MC_MESSAGE_RESTORE;
message.index = snapshot->privatization_index;
mc_model_checker->process().getChannel().send(message);
return client_.get();
}
+void Client::handleDeadlockCheck(mc_message_t* msg)
+{
+ bool deadlock = false;
+ if (not simix_global->process_list.empty()) {
+ deadlock = true;
+ for (auto kv : simix_global->process_list)
+ if (simgrid::mc::actor_is_enabled(kv.second)) {
+ deadlock = false;
+ break;
+ }
+ }
+
+ // Send result:
+ mc_message_int_t answer{MC_MESSAGE_DEADLOCK_CHECK_REPLY, deadlock};
+ xbt_assert(channel_.send(answer) == 0, "Could not send response");
+}
+void Client::handleContinue(mc_message_t* msg)
+{
+}
+void Client::handleSimcall(s_mc_message_simcall_handle_t* message)
+{
+ smx_actor_t process = SIMIX_process_from_PID(message->pid);
+ if (not process)
+ xbt_die("Invalid pid %lu", (unsigned long)message->pid);
+ SIMIX_simcall_handle(&process->simcall, message->value);
+ if (channel_.send(MC_MESSAGE_WAITING))
+ xbt_die("Could not send MESSAGE_WAITING to model-checker");
+}
+void Client::handleRestore(s_mc_message_restore_t* message)
+{
+#if HAVE_SMPI
+ smpi_really_switch_data_segment(message->index);
+#endif
+}
+
void Client::handleMessages()
{
while (1) {
XBT_DEBUG("Waiting messages from model-checker");
char message_buffer[MC_MESSAGE_LENGTH];
- ssize_t received_size;
+ ssize_t received_size = channel_.receive(&message_buffer, sizeof(message_buffer));
- if ((received_size = channel_.receive(&message_buffer, sizeof(message_buffer))) < 0)
+ if (received_size < 0)
xbt_die("Could not receive commands from the model-checker");
- s_mc_message_t message;
- if ((size_t)received_size < sizeof(message))
- xbt_die("Received message is too small");
- memcpy(&message, message_buffer, sizeof(message));
- switch (message.type) {
-
- case MC_MESSAGE_DEADLOCK_CHECK: {
- // Check deadlock:
- bool deadlock = false;
- if (not simix_global->process_list.empty()) {
- deadlock = true;
- for (auto kv : simix_global->process_list)
- if (simgrid::mc::actor_is_enabled(kv.second)) {
- deadlock = false;
- break;
- }
- }
-
- // Send result:
- s_mc_int_message_t answer;
- answer.type = MC_MESSAGE_DEADLOCK_CHECK_REPLY;
- answer.value = deadlock;
- xbt_assert(channel_.send(answer) == 0, "Could not send response");
- } break;
+ mc_message_t* message = (mc_message_t*)message_buffer;
+ switch (message->type) {
+
+ case MC_MESSAGE_DEADLOCK_CHECK:
+ xbt_assert(received_size == sizeof(mc_message_t), "Unexpected size for DEADLOCK_CHECK (%zu != %zu)",
+ received_size, sizeof(mc_message_t));
+ handleDeadlockCheck(message);
+ break;
case MC_MESSAGE_CONTINUE:
+ xbt_assert(received_size == sizeof(mc_message_t), "Unexpected size for MESSAGE_CONTINUE (%zu != %zu)",
+ received_size, sizeof(mc_message_t));
+ handleContinue(message);
return;
- case MC_MESSAGE_SIMCALL_HANDLE: {
- s_mc_simcall_handle_message_t message;
- if (received_size != sizeof(message))
- xbt_die("Unexpected size for SIMCALL_HANDLE");
- memcpy(&message, message_buffer, sizeof(message));
- smx_actor_t process = SIMIX_process_from_PID(message.pid);
- if (not process)
- xbt_die("Invalid pid %lu", (unsigned long)message.pid);
- SIMIX_simcall_handle(&process->simcall, message.value);
- if (channel_.send(MC_MESSAGE_WAITING))
- xbt_die("Could not send MESSAGE_WAITING to model-checker");
- } break;
-
- case MC_MESSAGE_RESTORE: {
- s_mc_restore_message_t message;
- if (received_size != sizeof(message))
- xbt_die("Unexpected size for SIMCALL_HANDLE");
- memcpy(&message, message_buffer, sizeof(message));
-#if HAVE_SMPI
- smpi_really_switch_data_segment(message.index);
-#endif
- } break;
+ case MC_MESSAGE_SIMCALL_HANDLE:
+ xbt_assert(received_size == sizeof(s_mc_message_simcall_handle_t),
+ "Unexpected size for SIMCALL_HANDLE (%zu != %zu)", received_size,
+ sizeof(s_mc_message_simcall_handle_t));
+ handleSimcall((s_mc_message_simcall_handle_t*)message_buffer);
+ break;
+
+ case MC_MESSAGE_RESTORE:
+ xbt_assert(received_size == sizeof(mc_message_t), "Unexpected size for MESSAGE_RESTORE (%zu != %zu)",
+ received_size, sizeof(mc_message_t));
+ handleRestore((s_mc_message_restore_t*)message_buffer);
+ break;
default:
- xbt_die("Received unexpected message %s (%i)", MC_message_type_name(message.type), message.type);
+ xbt_die("Received unexpected message %s (%i)", MC_message_type_name(message->type), message->type);
+ break;
}
}
}
void Client::ignoreMemory(void* addr, std::size_t size)
{
- s_mc_ignore_memory_message_t message;
+ s_mc_message_ignore_memory_t message;
message.type = MC_MESSAGE_IGNORE_MEMORY;
message.addr = (std::uintptr_t)addr;
message.size = size;
{
xbt_mheap_t heap = mmalloc_get_current_heap();
- s_mc_ignore_heap_message_t message;
+ s_mc_message_ignore_heap_t message;
message.type = MC_MESSAGE_IGNORE_HEAP;
message.address = address;
message.size = size;
void Client::unignoreHeap(void* address, std::size_t size)
{
- s_mc_ignore_memory_message_t message;
+ s_mc_message_ignore_memory_t message;
message.type = MC_MESSAGE_UNIGNORE_HEAP;
message.addr = (std::uintptr_t)address;
message.size = size;
#endif
region.process_index = -1;
- s_mc_stack_region_message_t message;
+ s_mc_message_stack_region_t message;
message.type = MC_MESSAGE_STACK_REGION;
message.stack_region = region;
if (channel_.send(message))
Client();
explicit Client(int fd) : active_(true), channel_(fd) {}
void handleMessages();
+
+private:
+ void handleDeadlockCheck(mc_message_t* msg);
+ void handleContinue(mc_message_t* msg);
+ void handleSimcall(s_mc_message_simcall_handle_t* message);
+ void handleRestore(s_mc_message_restore_t* msg);
+
+public:
Channel const& getChannel() const { return channel_; }
Channel& getChannel() { return channel_; }
void mainLoop();
*
* Moreover the protocol is not stable. The same version of the library should be used
* for the client and the server.
- *
- * This is the basic structure shared by all messages: all message start with a message
- * type.
*/
+
+/* Basic structure: all message start with a message type */
struct s_mc_message {
e_mc_message_type type;
};
-typedef struct s_mc_message s_mc_message_t;
-typedef struct s_mc_message* mc_message_t;
+typedef struct s_mc_message mc_message_t;
-struct s_mc_int_message {
+struct s_mc_message_int {
e_mc_message_type type;
uint64_t value;
};
-typedef struct s_mc_int_message s_mc_int_message_t;
-typedef struct s_mc_int_message* mc_int_message_t;
+typedef struct s_mc_message_int mc_message_int_t;
-struct s_mc_ignore_heap_message {
+struct s_mc_message_ignore_heap {
e_mc_message_type type;
int block;
int fragment;
void* address;
size_t size;
};
-typedef struct s_mc_ignore_heap_message s_mc_ignore_heap_message_t;
-typedef struct s_mc_ignore_heap_message* mc_ignore_heap_message_t;
+typedef struct s_mc_message_ignore_heap s_mc_message_ignore_heap_t;
-struct s_mc_ignore_memory_message {
+struct s_mc_message_ignore_memory {
e_mc_message_type type;
uint64_t addr;
size_t size;
};
-typedef struct s_mc_ignore_memory_message s_mc_ignore_memory_message_t;
-typedef struct s_mc_ignore_memory_message* mc_ignore_memory_message_t;
+typedef struct s_mc_message_ignore_memory s_mc_message_ignore_memory_t;
-struct s_mc_stack_region_message {
+struct s_mc_message_stack_region {
e_mc_message_type type;
s_stack_region_t stack_region;
};
-typedef struct s_mc_stack_region_message s_mc_stack_region_message_t;
-typedef struct s_mc_stack_region_message* mc_stack_region_message_t;
+typedef struct s_mc_message_stack_region s_mc_message_stack_region_t;
-struct s_mc_simcall_handle_message {
+struct s_mc_message_simcall_handle {
e_mc_message_type type;
unsigned long pid;
int value;
};
-typedef struct s_mc_simcall_handle_message s_mc_simcall_handle_message_t;
-typedef struct s_mc_simcall_handle_message* mc_simcall_handle_message;
+typedef struct s_mc_message_simcall_handle s_mc_message_simcall_handle_t;
struct s_mc_register_symbol_message {
e_mc_message_type type;
void* data;
};
typedef struct s_mc_register_symbol_message s_mc_register_symbol_message_t;
-typedef struct s_mc_register_symbol_message* mc_register_symbol_message_t;
-struct s_mc_restore_message {
+struct s_mc_message_restore {
e_mc_message_type type;
int index;
};
-typedef struct s_mc_restore_message s_mc_restore_message_t;
-typedef struct s_mc_restore_message* mc_restore_message_t;
+typedef struct s_mc_message_restore s_mc_message_restore_t;
XBT_PRIVATE const char* MC_message_type_name(e_mc_message_type type);