Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
71bd4ed173e3cf132a31188010431a4112bf4482
[simgrid.git] / src / simix / popping_private.h
1 /* Copyright (c) 2007-2010, 2012-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 #ifndef _POPPING_PRIVATE_H
8 #define _POPPING_PRIVATE_H
9
10 #include <xbt/base.h>
11 #include <simgrid/simix.h>
12
13 SG_BEGIN_DECL()
14
15 /********************************* Simcalls *********************************/
16 XBT_PUBLIC_DATA(const char*) simcall_names[]; /* Name of each simcall */
17
18 #include "popping_enum.h" /* Definition of e_smx_simcall_t, with one value per simcall */
19
20 typedef int (*simix_match_func_t)(void *, void *, smx_synchro_t);
21 typedef void (*simix_copy_data_func_t)(smx_synchro_t, void*, size_t);
22 typedef void (*simix_clean_func_t)(void *);
23 typedef void (*FPtr)(void); // Hide the ugliness
24
25 /* Pack all possible scalar types in an union */
26 union u_smx_scalar {
27   char            c;
28   const char*     cc;
29   short           s;
30   int             i;
31   long            l;
32   unsigned char   uc;
33   unsigned short  us;
34   unsigned int    ui;
35   unsigned long   ul;
36   float           f;
37   double          d;
38   size_t          sz;
39   sg_size_t       sgsz;
40   sg_offset_t     sgoff;
41   void*           dp;
42   FPtr            fp;
43   const void*     cp;
44 };
45
46 /**
47  * \brief Represents a simcall to the kernel.
48  */
49 typedef struct s_smx_simcall {
50   e_smx_simcall_t call;
51   smx_process_t issuer;
52   int mc_value;
53   union u_smx_scalar args[11];
54   union u_smx_scalar result;
55 } s_smx_simcall_t, *smx_simcall_t;
56
57 #define SIMCALL_SET_MC_VALUE(simcall, value) ((simcall)->mc_value = (value))
58 #define SIMCALL_GET_MC_VALUE(simcall) ((simcall)->mc_value)
59
60 #include "popping_accessors.h"
61
62 /******************************** General *************************************/
63
64 XBT_PRIVATE void SIMIX_simcall_answer(smx_simcall_t);
65 XBT_PRIVATE void SIMIX_simcall_handle(smx_simcall_t, int);
66 XBT_PRIVATE void SIMIX_simcall_exit(smx_synchro_t);
67 XBT_PRIVATE const char *SIMIX_simcall_name(e_smx_simcall_t kind);
68 XBT_PRIVATE void SIMIX_run_kernel(void* code);
69
70 SG_END_DECL()
71
72 #ifdef __cplusplus
73
74 namespace simgrid {
75 namespace simix {
76
77 template<typename T> struct marshal_t {};
78 #define SIMIX_MARSHAL(T, field) \
79   template<> struct marshal_t<T> { \
80     static void marshal(u_smx_scalar& simcall, T value) \
81     { \
82       simcall.field = value; \
83     } \
84     static T unmarshal(u_smx_scalar const& simcall) \
85     { \
86       return simcall.field; \
87     } \
88   };
89
90 SIMIX_MARSHAL(char, c);
91 SIMIX_MARSHAL(short, s);
92 SIMIX_MARSHAL(int, i);
93 SIMIX_MARSHAL(long, l);
94 SIMIX_MARSHAL(unsigned char, uc);
95 SIMIX_MARSHAL(unsigned short, us);
96 SIMIX_MARSHAL(unsigned int, ui);
97 SIMIX_MARSHAL(unsigned long, ul);
98 SIMIX_MARSHAL(float, f);
99 SIMIX_MARSHAL(double, d);
100 SIMIX_MARSHAL(FPtr, fp);
101
102 template<typename T> struct marshal_t<T*> {
103   static void marshal(u_smx_scalar& simcall, T* value)
104   {
105     simcall.dp = value;
106   }
107   static T* unmarshal(u_smx_scalar const& simcall)
108   {
109     return simcall.dp;
110   }
111 };
112
113 template<> struct marshal_t<void> {
114   static void unmarshal(u_smx_scalar const& simcall) {}
115 };
116
117 template<class T> inline
118 void marshal(u_smx_scalar& simcall, T const& value)
119 {
120   marshal_t<T>::marshal(simcall, value);
121 }
122
123 template<class T> inline
124 T unmarshal(u_smx_scalar const& simcall)
125 {
126   return marshal_t<T>::unmarshal(simcall);
127 }
128
129 template<class A> inline
130 void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a)
131 {
132   simcall->call = call;
133   memset(&simcall->result, 0, sizeof(simcall->result));
134   marshal(simcall->args[0], std::forward<A>(a));
135 }
136
137 template<class A, class B> inline
138 void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b)
139 {
140   simcall->call = call;
141   memset(&simcall->result, 0, sizeof(simcall->result));
142   marshal(simcall->args[0], std::forward<A>(a));
143   marshal(simcall->args[1], std::forward<B>(b));
144 }
145
146 template<class A, class B, class C> inline
147 void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b, C&& c)
148 {
149   simcall->call = call;
150   memset(&simcall->result, 0, sizeof(simcall->result));
151   marshal(simcall->args[0], std::forward<A>(a));
152   marshal(simcall->args[1], std::forward<B>(b));
153   marshal(simcall->args[2], std::forward<C>(c));
154 }
155
156 template<class A, class B, class C, class D> inline
157 void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b, C&& c, D&& d)
158 {
159   simcall->call = call;
160   memset(&simcall->result, 0, sizeof(simcall->result));
161   marshal(simcall->args[0], std::forward<A>(a));
162   marshal(simcall->args[1], std::forward<B>(b));
163   marshal(simcall->args[2], std::forward<C>(c));
164   marshal(simcall->args[3], std::forward<D>(d));
165 }
166
167 template<class A, class B, class C, class D, class E> inline
168 void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A&& a, B&& b, C&& c, D&& d, E&& e)
169 {
170   simcall->call = call;
171   memset(&simcall->result, 0, sizeof(simcall->result));
172   marshal(simcall->args[0], std::forward<A>(a));
173   marshal(simcall->args[1], std::forward<B>(b));
174   marshal(simcall->args[2], std::forward<C>(c));
175   marshal(simcall->args[3], std::forward<D>(d));
176   marshal(simcall->args[4], std::forward<E>(e));
177 }
178
179 template<class A, class B, class C, class D, class E, class F> inline
180 void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
181   A&& a, B&& b, C&& c, D&& d, E&& e, F&& f)
182 {
183   simcall->call = call;
184   memset(&simcall->result, 0, sizeof(simcall->result));
185   marshal(simcall->args[0], std::forward<A>(a));
186   marshal(simcall->args[1], std::forward<B>(b));
187   marshal(simcall->args[2], std::forward<C>(c));
188   marshal(simcall->args[3], std::forward<D>(d));
189   marshal(simcall->args[4], std::forward<E>(e));
190   marshal(simcall->args[5], std::forward<F>(f));
191 }
192
193 template<class A, class B, class C, class D, class E, class F, class G> inline
194 void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
195   A&& a, B&& b, C&& c, D&& d, E&& e, F&& f, G&& g)
196 {
197   simcall->call = call;
198   memset(&simcall->result, 0, sizeof(simcall->result));
199   marshal(simcall->args[0], std::forward<A>(a));
200   marshal(simcall->args[1], std::forward<B>(b));
201   marshal(simcall->args[2], std::forward<C>(c));
202   marshal(simcall->args[3], std::forward<D>(d));
203   marshal(simcall->args[4], std::forward<E>(e));
204   marshal(simcall->args[5], std::forward<F>(f));
205   marshal(simcall->args[6], std::forward<G>(g));
206 }
207
208 template<class A, class B, class C,
209           class D, class E, class F, class G, class H> inline
210 void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
211   A&& a, B&& b, C&& c, D&& d, E&& e, F&& f, G&& g, H&& h)
212 {
213   simcall->call = call;
214   memset(&simcall->result, 0, sizeof(simcall->result));
215   marshal(simcall->args[0], std::forward<A>(a));
216   marshal(simcall->args[1], std::forward<B>(b));
217   marshal(simcall->args[2], std::forward<C>(c));
218   marshal(simcall->args[3], std::forward<D>(d));
219   marshal(simcall->args[4], std::forward<E>(e));
220   marshal(simcall->args[5], std::forward<F>(f));
221   marshal(simcall->args[6], std::forward<G>(g));
222   marshal(simcall->args[7], std::forward<H>(h));
223 }
224
225 template<class A, class B, class C,
226           class D, class E, class F,
227           class G, class H, class I> inline
228 void marshal(smx_simcall_t simcall, e_smx_simcall_t call,
229   A&& a, B&& b, C&& c, D&& d, E&& e, F&& f, G&& g, H&& h, I&& i)
230 {
231   simcall->call = call;
232   memset(&simcall->result, 0, sizeof(simcall->result));
233   marshal(simcall->args[0], std::forward<A>(a));
234   marshal(simcall->args[1], std::forward<B>(b));
235   marshal(simcall->args[2], std::forward<C>(c));
236   marshal(simcall->args[3], std::forward<D>(d));
237   marshal(simcall->args[4], std::forward<E>(e));
238   marshal(simcall->args[5], std::forward<F>(f));
239   marshal(simcall->args[6], std::forward<G>(g));
240   marshal(simcall->args[7], std::forward<H>(h));
241   marshal(simcall->args[8], std::forward<I>(i));
242 }
243
244 }
245 }
246
247 #endif
248
249 #endif