Logo AND Algorithmique Numérique Distribuée

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