Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
9caade7396522e979ca46cf8e0bc42219c46abfc
[simgrid.git] / src / mc / mc_client.cpp
1 /* Copyright (c) 2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <cstdlib>
8 #include <cerrno>
9
10 #include <sys/types.h>
11 #include <sys/socket.h>
12
13 #include <xbt/log.h>
14 #include <xbt/sysdep.h>
15 #include <xbt/mmalloc.h>
16
17 #include "mc_protocol.h"
18 #include "mc_client.h"
19
20 // We won't need those once the separation MCer/MCed is complete:
21 #include "mc_mmalloc.h"
22 #include "mc_ignore.h"
23 #include "mc_private.h" // MC_deadlock_check()
24 #include "mc_smx.h"
25
26 extern "C" {
27
28 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_client, mc, "MC client logic");
29
30 mc_client_t mc_client;
31
32 void MC_client_init(void)
33 {
34   if (mc_client) {
35     XBT_WARN("MC_client_init called more than once.");
36     return;
37   }
38
39   char* fd_env = std::getenv(MC_ENV_SOCKET_FD);
40   if (!fd_env)
41     xbt_die("MC socket not found");
42
43   int fd = atoi(fd_env);
44   XBT_DEBUG("Model-checked application found socket FD %i", fd);
45
46   int type;
47   socklen_t socklen = sizeof(type);
48   if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &socklen) != 0)
49     xbt_die("Could not check socket type");
50   if (type != SOCK_DGRAM)
51     xbt_die("Unexpected socket type %i", type);
52   XBT_DEBUG("Model-checked application found expected socket type");
53
54   mc_client = xbt_new0(s_mc_client_t, 1);
55   mc_client->fd = fd;
56   mc_client->active = 1;
57 }
58
59 void MC_client_send_message(void* message, size_t size)
60 {
61   if (MC_protocol_send(mc_client->fd, message, size))
62     xbt_die("Could not send message %i", (int) ((mc_message_t)message)->type);
63 }
64
65 void MC_client_send_simple_message(e_mc_message_type type)
66 {
67   if (MC_protocol_send_simple_message(mc_client->fd, type))
68     xbt_die("Could not send message %i", type);
69 }
70
71 void MC_client_handle_messages(void)
72 {
73   while (1) {
74     XBT_DEBUG("Waiting messages from model-checker");
75
76     char message_buffer[MC_MESSAGE_LENGTH];
77     ssize_t s;
78     if ((s = MC_receive_message(mc_client->fd, &message_buffer, sizeof(message_buffer), 0)) < 0)
79       xbt_die("Could not receive commands from the model-checker");
80
81     s_mc_message_t message;
82     if ((size_t) s < sizeof(message))
83       xbt_die("Received message is too small");
84     memcpy(&message, message_buffer, sizeof(message));
85     switch (message.type) {
86
87     case MC_MESSAGE_DEADLOCK_CHECK:
88       {
89         int result = MC_deadlock_check();
90         s_mc_int_message_t answer;
91         answer.type = MC_MESSAGE_DEADLOCK_CHECK_REPLY;
92         answer.value = result;
93         if (MC_protocol_send(mc_client->fd, &answer, sizeof(answer)))
94           xbt_die("Could not send response");
95       }
96       break;
97
98     case MC_MESSAGE_CONTINUE:
99       return;
100
101     case MC_MESSAGE_SIMCALL_HANDLE:
102       {
103         s_mc_simcall_handle_message_t message;
104         if (s != sizeof(message))
105           xbt_die("Unexpected size for SIMCALL_HANDLE");
106         memcpy(&message, message_buffer, sizeof(message));
107         smx_process_t process = SIMIX_process_from_PID(message.pid);
108         if (!process)
109           xbt_die("Invalid pid %lu", (unsigned long) message.pid);
110         SIMIX_simcall_handle(&process->simcall, message.value);
111         MC_protocol_send_simple_message(mc_client->fd, MC_MESSAGE_WAITING);
112       }
113       break;
114
115     case MC_MESSAGE_RESTORE:
116       {
117         s_mc_restore_message_t message;
118         if (s != sizeof(message))
119           xbt_die("Unexpected size for SIMCALL_HANDLE");
120         memcpy(&message, message_buffer, sizeof(message));
121         smpi_really_switch_data_segment(message.index);
122       }
123       break;
124
125     default:
126       xbt_die("%s received unexpected message %s (%i)",
127         MC_mode_name(mc_mode),
128         MC_message_type_name(message.type),
129         message.type
130       );
131     }
132   }
133 }
134
135 void MC_client_main_loop(void)
136 {
137   while (1) {
138     MC_protocol_send_simple_message(mc_client->fd, MC_MESSAGE_WAITING);
139     MC_client_handle_messages();
140     MC_wait_for_requests();
141   }
142 }
143
144 }