/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- DMTCP_NEXT_EVENT_HOOK
1 /****************************************************************************
2 * TODO: Replace this header with appropriate header showing MIT OR BSD *
3 * License *
4 * Copyright (C) 2006-2008 by Jason Ansel, Kapil Arya, and Gene Cooperman *
5 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
6 * *
7 * This file, dmtcp.h, is placed in the public domain. *
8 * The motivation for this is to allow anybody to freely use this file *
9 * without restriction to statically link this file with any software. *
10 * This allows that software to communicate with the DMTCP libraries. *
11 * - Jason Ansel, Kapil Arya, and Gene Cooperman *
12 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
13 ****************************************************************************/
14
15 #ifndef DMTCP_H
16 #define DMTCP_H
17
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/ip.h>
22
23 #ifndef __USE_GNU
24 # define __USE_GNU_NOT_SET
25 # define __USE_GNU
26 #endif
27 #include <dlfcn.h> /* for NEXT_FNC() */
28 #ifdef __USE_GNU_NOT_SET
29 # undef __USE_GNU_NOT_SET
30 # undef __USE_GNU
31 #endif
32
33 #ifndef EXTERNC
34 # ifdef __cplusplus
35 # define EXTERNC extern "C"
36 # else
37 # define EXTERNC
38 # endif
39 #endif
40
41 // C++ takes null arg, while C takes void arg.
42 #ifdef __cplusplus
43 # define VOID
44 #else
45 # define VOID void
46 #endif
47
48 #define LIB_PRIVATE __attribute__ ((visibility ("hidden")))
49
50 typedef enum eDmtcpEvent {
51 //DMTCP_EVENT_WRAPPER_INIT, // Future Work :-).
52 DMTCP_EVENT_INIT,
53 DMTCP_EVENT_EXIT,
54
55 DMTCP_EVENT_PRE_EXEC,
56 DMTCP_EVENT_POST_EXEC,
57
58 DMTCP_EVENT_ATFORK_PREPARE,
59 DMTCP_EVENT_ATFORK_PARENT,
60 DMTCP_EVENT_ATFORK_CHILD,
61
62 DMTCP_EVENT_WAIT_FOR_SUSPEND_MSG,
63 DMTCP_EVENT_THREADS_SUSPEND,
64 DMTCP_EVENT_LEADER_ELECTION,
65 DMTCP_EVENT_DRAIN,
66 DMTCP_EVENT_WRITE_CKPT,
67
68 DMTCP_EVENT_RESTART,
69 DMTCP_EVENT_RESUME,
70 DMTCP_EVENT_REGISTER_NAME_SERVICE_DATA,
71 DMTCP_EVENT_SEND_QUERIES,
72 DMTCP_EVENT_REFILL,
73 DMTCP_EVENT_THREADS_RESUME,
74
75 DMTCP_EVENT_PRE_SUSPEND_USER_THREAD,
76 DMTCP_EVENT_RESUME_USER_THREAD,
77
78 DMTCP_EVENT_THREAD_START,
79 DMTCP_EVENT_THREAD_CREATED,
80
81 DMTCP_EVENT_PTHREAD_START,
82 DMTCP_EVENT_PTHREAD_EXIT,
83 DMTCP_EVENT_PTHREAD_RETURN,
84
85 nDmtcpEvents
86 } DmtcpEvent_t;
87
88 typedef union _DmtcpEventData_t {
89 struct {
90 int fd;
91 } serializerInfo;
92
93 struct {
94 int isRestart;
95 } resumeUserThreadInfo, refillInfo, resumeInfo, nameserviceInfo;
96 } DmtcpEventData_t;
97
98 typedef struct DmtcpUniqueProcessId {
99 uint64_t _hostid; //gethostid()
100 uint64_t _time; //time()
101 pid_t _pid; //getpid()
102 uint32_t _computation_generation; //computationGeneration()
103 } DmtcpUniqueProcessId;
104
105 EXTERNC int dmtcp_unique_pids_equal(DmtcpUniqueProcessId a,
106 DmtcpUniqueProcessId b);
107
108 //FIXME:
109 // If a plugin is not compiled with defined(__PIC__) and we can verify
110 // that we're using DMTCP (environment variables), and dmtcp_is_enabled
111 // or dmtcp_checkpoint expands to 0, then we should print a warning
112 // at run-time.
113
114 // These utility functions require compiling the target app with -fPIC
115
116 /**
117 * Returns 1 if executing under dmtcp_launch, 0 otherwise
118 * See: test/plugin/applic-initiated-ckpt and applic-delayed-ckpt
119 * directories for exammples:
120 */
121 EXTERNC int dmtcp_is_enabled(VOID) __attribute ((weak));
122 #define dmtcp_is_enabled() (dmtcp_is_enabled ? dmtcp_is_enabled() : 0)
123
124 /**
125 * Checkpoint the entire distributed computation
126 * (Does not necessarily block until checkpoint is complete.
127 * Use dmtcp_get_generation() to test if checkpoint is complete.)
128 * + returns DMTCP_AFTER_CHECKPOINT if the checkpoint succeeded.
129 * + returns DMTCP_AFTER_RESTART after a restart.
130 * + returns <=0 on error.
131 * See: test/plugin/applic-initiated-ckpt directory for an exammple:
132 */
133 EXTERNC int dmtcp_checkpoint(VOID) __attribute__ ((weak));
134 #define dmtcp_checkpoint() \
135 (dmtcp_checkpoint ? dmtcp_checkpoint() : DMTCP_NOT_PRESENT)
136
137 /**
138 * Prevent a checkpoint from starting until dmtcp_enable_checkpoint() is
139 * called.
140 * + Has (recursive) lock semantics, only one thread may acquire it at time.
141 * + Only prevents checkpoints locally, remote processes may be suspended.
142 * Thus, send or recv to another checkpointed process may create deadlock.
143 * + Returns 1 on success, <=0 on error
144 * See: test/plugin/applic-delayed-ckpt directory for an exammple:
145 */
146 EXTERNC int dmtcp_disable_ckpt(VOID) __attribute__ ((weak));
147 #define dmtcp_disable_ckpt() \
148 (dmtcp_disable_ckpt ? dmtcp_disable_ckpt() : DMTCP_NOT_PRESENT)
149
150 /**
151 * Re-allow checkpoints, opposite of dmtcp_disable_checkpoint().
152 * + Returns 1 on success, <=0 on error
153 * See: test/plugin/applic-delayed-ckpt directory for an exammple:
154 */
155 EXTERNC int dmtcp_enable_ckpt(VOID) __attribute__ ((weak));
156 #define dmtcp_enable_ckpt() \
157 (dmtcp_enable_ckpt ? dmtcp_enable_ckpt() : DMTCP_NOT_PRESENT)
158
159 // See: test/plugin/sleep1 dir and sibling directories for examples:
160 EXTERNC void dmtcp_event_hook(DmtcpEvent_t event, DmtcpEventData_t *data)
161 __attribute((weak));
162
163 // See: test/plugin/example-db dir for an example:
164 EXTERNC int dmtcp_send_key_val_pair_to_coordinator(const char *id,
165 const void *key,
166 uint32_t key_len,
167 const void *val,
168 uint32_t val_len);
169 EXTERNC int dmtcp_send_key_val_pair_to_coordinator_sync(const char *id,
170 const void *key,
171 uint32_t key_len,
172 const void *val,
173 uint32_t val_len);
174 EXTERNC int dmtcp_send_query_to_coordinator(const char *id,
175 const void *key, uint32_t key_len,
176 void *val, uint32_t *val_len);
177
178 EXTERNC void dmtcp_get_local_ip_addr(struct in_addr *in);
179
180 EXTERNC const char* dmtcp_get_tmpdir(void);
181 //EXTERNC void dmtcp_set_tmpdir(const char *);
182
183 EXTERNC const char* dmtcp_get_ckpt_dir(void);
184 EXTERNC void dmtcp_set_ckpt_dir(const char *);
185 EXTERNC const char* dmtcp_get_coord_ckpt_dir(void);
186 EXTERNC void dmtcp_set_coord_ckpt_dir(const char* dir);
187 EXTERNC const char* dmtcp_get_ckpt_filename(void) __attribute__((weak));
188 EXTERNC const char* dmtcp_get_ckpt_files_subdir(void);
189 EXTERNC int dmtcp_should_ckpt_open_files(void);
190
191 EXTERNC int dmtcp_get_ckpt_signal(void);
192 EXTERNC const char* dmtcp_get_uniquepid_str(void) __attribute__((weak));
193
194 /*
195 * ComputationID
196 * ComputationID of a computation is the unique-pid of the first process of
197 * the computation. Even if that process dies, the rest of the computation
198 * retains the same computation ID.
199 *
200 * With --enable-unique-checkpoint-filenames, the ComputationID also includes
201 * the checkpoint generation number (starting from 1 for the first
202 * checkpoint). This number is the same for the entire computation at a
203 * given point in time. Dmtcp coordinator increments this number prior
204 * to sending the SUSPEND message, and it is sent to the workers as a part
205 * of the SUSPEND message.
206 */
207 EXTERNC const char* dmtcp_get_computation_id_str(void);
208 EXTERNC uint64_t dmtcp_get_coordinator_timestamp(void);
209 // Generation is 0 before first checkpoint, and then successively incremented.
210 EXTERNC uint32_t dmtcp_get_generation(void) __attribute__((weak));
211 EXTERNC int checkpoint_is_pending(void) __attribute__((weak));
212
213 /**
214 * Gets the coordinator-specific status of DMTCP.
215 * - Returns 0 on success and -1 on error.
216 *
217 * Args:
218 * numPeers: Number of processes connected to dmtcp_coordinator
219 * isRunning: 1 if all processes connected to dmtcp_coordinator are in a
220 * running state
221 */
222 EXTERNC int dmtcp_get_coordinator_status(int *numPeers, int *isRunning)
223 __attribute__((weak));
224 #define dmtcp_get_coordinator_status(p,r) \
225 (dmtcp_get_coordinator_status ? dmtcp_get_coordinator_status(p,r) \
226 : DMTCP_NOT_PRESENT)
227
228 /**
229 * Queries local state of this process, not global state seen by DMTCP coord.
230 * + Returns 0 on success and -1 on error.
231 *
232 * Args:
233 * numCheckpoints: The number of times this process has been checkpointed
234 * (excludes restarts)
235 * numRestarts: The number of times this process has been restarted
236 */
237 EXTERNC int dmtcp_get_local_status(int *numCheckpoints, int *numRestarts)
238 __attribute__((weak));
239 #define dmtcp_get_local_status(c,r) \
240 (dmtcp_get_local_status ? dmtcp_get_local_status(c,r) : DMTCP_NOT_PRESENT)
241
242 // Is DMTCP in the running state?
243 // (e.g., not in pre-ckpt, post-ckpt, post-restart event)?
244 EXTERNC int dmtcp_is_running_state(void);
245 // Primarily for use by the modify-env plugin.
246 EXTERNC int dmtcp_get_restart_env(const char *name,
247 char *value, size_t maxvaluelen);
248 // Get pathname of target executable under DMTCP control.
249 EXTERNC const char* dmtcp_get_executable_path();
250 // True if dmtcp_launch called with --no-coordinator
251 EXTERNC int dmtcp_no_coordinator(void);
252 // True in early stages of dmtcp_launch; If true, DMTCP may not be stable yet.
253 EXTERNC int dmtcp_is_initializing_wrappers(void);
254 /* If your plugin invokes wrapper functions before DMTCP is initialized,
255 * then call this prior to your first wrapper function call.
256 */
257 EXTERNC void dmtcp_prepare_wrappers(void) __attribute((weak));
258
259 // FOR EXPERTS ONLY:
260 EXTERNC int dmtcp_is_protected_fd(int fd);
261 EXTERNC DmtcpUniqueProcessId dmtcp_get_uniquepid();
262 EXTERNC DmtcpUniqueProcessId dmtcp_get_coord_id();
263 EXTERNC DmtcpUniqueProcessId dmtcp_get_computation_id();
264
265 // FOR EXPERTS ONLY:
266 EXTERNC int dmtcp_get_ptrace_fd(void);
267 EXTERNC int dmtcp_get_readlog_fd(void);
268 EXTERNC void dmtcp_block_ckpt_signal(void);
269 EXTERNC void dmtcp_unblock_ckpt_signal(void);
270
271 // FOR EXPERTS ONLY:
272 EXTERNC void *dmtcp_get_libc_dlsym_addr(void);
273 EXTERNC void dmtcp_close_protected_fd(int fd);
274 EXTERNC int dmtcp_protected_environ_fd(void);
275
276 /* FOR EXPERTS ONLY:
277 * The DMTCP internal pid plugin ensures that the application sees only
278 * a virtual pid, which can be translated to the current real pid
279 * assigned to the kernel on a restart. The pid plugin places wrappers
280 * around all system calls referring to a pid. If your application
281 * discovers a pid without going through a system call (e.g., through
282 * the proc filesystem), use this to virtualize the pid.
283 */
284 EXTERNC pid_t dmtcp_real_to_virtual_pid(pid_t realPid) __attribute((weak));
285 EXTERNC pid_t dmtcp_virtual_to_real_pid(pid_t virtualPid) __attribute((weak));
286
287 // bq_file -> "batch queue file"; used only by batch-queue plugin
288 EXTERNC int dmtcp_is_bq_file(const char *path)
289 __attribute((weak));
290 EXTERNC int dmtcp_bq_should_ckpt_file(const char *path, int *type)
291 __attribute((weak));
292 EXTERNC int dmtcp_bq_restore_file(const char *path, const char *savedFilePath,
293 int fcntlFlags, int type)
294 __attribute((weak));
295
296 /* These next two functions are defined in contrib/ckptfile/ckptfile.cpp
297 * But they are currently used only in src/plugin/ipc/file/fileconnection.cpp
298 * and in a trivial fashion. These are intended for future extensions.
299 */
300 EXTERNC int dmtcp_must_ckpt_file(const char *path) __attribute((weak));
301 EXTERNC void dmtcp_get_new_file_path(const char *abspath, const char *cwd,
302 char *newpath)
303 __attribute((weak));
304
305 #define dmtcp_process_event(e,d) \
306 __REPLACE_dmtcp_process_event_WITH_dmtcp_event_hook()__
307
308 // These are part of the internal implementation of DMTCP plugins
309 EXTERNC int dmtcp_plugin_disable_ckpt(void);
310 #define DMTCP_PLUGIN_DISABLE_CKPT() \
311 int __dmtcp_plugin_ckpt_disabled = dmtcp_plugin_disable_ckpt()
312
313 EXTERNC void dmtcp_plugin_enable_ckpt(void);
314 #define DMTCP_PLUGIN_ENABLE_CKPT() \
315 if (__dmtcp_plugin_ckpt_disabled) dmtcp_plugin_enable_ckpt()
316
317
318 #define NEXT_FNC(func) \
319 ({ \
320 static __typeof__(&func) _real_##func = (__typeof__(&func)) -1; \
321 if (_real_##func == (__typeof__(&func)) -1) { \
322 if (dmtcp_prepare_wrappers) dmtcp_prepare_wrappers(); \
323 __typeof__(&dlsym) dlsym_fnptr; \
324 dlsym_fnptr = (__typeof__(&dlsym)) dmtcp_get_libc_dlsym_addr(); \
325 _real_##func = (__typeof__(&func)) (*dlsym_fnptr) (RTLD_NEXT, #func);\
326 } \
327 _real_##func;})
328
329 static void DMTCP_NEXT_EVENT_HOOK(event, data) {
330 do {
331 static __typeof__(&dmtcp_event_hook) fn
332 = (__typeof__(&dmtcp_event_hook)) -1;
333 if ((void*) fn == (void*) -1) {
334 fn = NEXT_FNC(dmtcp_event_hook);
335 }
336 if (fn != NULL) {
337 (*fn) (event, data);
338 }
339 } while (0);
340 }
341
342 //===================================================================
343 // DMTCP utilities
344
345 #ifndef DMTCP_AFTER_CHECKPOINT
346 // Return value of dmtcp_checkpoint
347 # define DMTCP_AFTER_CHECKPOINT 1
348 // Return value of dmtcp_checkpoint
349 # define DMTCP_AFTER_RESTART 2
350 #endif
351 #ifndef DMTCP_NOT_PRESENT
352 # define DMTCP_NOT_PRESENT 3
353 #endif
354
355 #define dmtcp_get_ckpt_filename() \
356 (dmtcp_get_ckpt_filename ? dmtcp_get_ckpt_filename() : NULL)
357
358 #define dmtcp_get_uniquepid_str() \
359 (dmtcp_get_uniquepid_str ? dmtcp_get_uniquepid_str() : NULL)
360
361 /// Pointer to a "void foo();" function
362 typedef void (*dmtcp_fnptr_t)(void);
363
364 #endif