Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
get the good parts of the replay without stack into the regular replay
[simgrid.git] / src / replay / state_machine_context.c
1 /* Copyright (c) 2010. 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 <setjmp.h>
8 #include "replay.h"
9
10 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(replay);
11 typedef struct s_statem_context {
12   s_smx_ctx_base_t base;
13   void *user_data;
14   jmp_buf jump;
15   int syscall_id; /* Identifier of previous syscall to SIMIX */
16 } s_statem_context_t,*statem_context_t;
17
18 static smx_context_t
19 statem_create_context(xbt_main_func_t code, int argc, char **argv,
20     void_pfn_smxprocess_t cleanup_func, void *data);
21
22 static void statem_ctx_free(smx_context_t context);
23 static void statem_ctx_suspend(smx_context_t context);
24 static void statem_ctx_resume(smx_context_t new_context);
25 static void statem_ctx_runall(xbt_dynar_t processes);
26 static smx_context_t statem_ctx_self(void);
27
28 void statem_factory_init(smx_context_factory_t * factory) {
29   /* instantiate the context factory */
30   smx_ctx_base_factory_init(factory);
31
32   (*factory)->create_context = statem_create_context;
33   (*factory)->free = statem_ctx_free;
34   (*factory)->suspend = statem_ctx_suspend;
35   (*factory)->runall = statem_ctx_runall;
36   (*factory)->name = "State Machine context factory";
37 }
38
39 static smx_context_t
40 statem_create_context(xbt_main_func_t code, int argc, char **argv,
41     void_pfn_smxprocess_t cleanup_func, void *data){
42   if(argc>0 && !replay_func_init) {
43     fprintf(stderr,"variable replay_initer_function not set in replay_create_context. Severe issue!");
44   }
45
46   statem_context_t res = (statem_context_t)
47   smx_ctx_base_factory_create_context_sized(sizeof(s_statem_context_t),
48       code, argc, argv,
49       cleanup_func,
50       data);
51
52   if (argc>0) /* not maestro */
53     res->user_data = replay_func_init(argc,argv);
54   return (smx_context_t)res;
55 }
56
57 static void statem_ctx_free(smx_context_t context) {
58   if (replay_func_fini)
59     replay_func_fini(((statem_context_t)context)->user_data);
60   else if (((statem_context_t)context)->user_data)
61     free(((statem_context_t)context)->user_data);
62
63   smx_ctx_base_free(context);
64 }
65 /*static void replay_ctx_stop(smx_context_t context) {
66   THROW_UNIMPLEMENTED;
67 }*/
68 static void statem_ctx_suspend(smx_context_t context) {
69   statem_context_t ctx = (statem_context_t)context;
70   ctx->syscall_id = SIMIX_request_last_id();
71   longjmp(ctx->jump,1);
72 }
73 static void statem_ctx_resume(smx_context_t new_context) {
74   THROW_UNIMPLEMENTED;
75 }
76 static void statem_ctx_runall(xbt_dynar_t processes) {
77   smx_context_t old_context;
78   smx_process_t process;
79   unsigned int cursor;
80
81   INFO0("Run all");
82
83   xbt_dynar_foreach(processes, cursor, process) {
84     statem_context_t ctx = (statem_context_t)SIMIX_process_get_context(process);
85     old_context = smx_current_context;
86     smx_current_context = SIMIX_process_get_context(process);
87     if (!setjmp(ctx->jump))
88       replay_func_run(((statem_context_t)smx_current_context)->user_data,
89           ctx->syscall_id==0?NULL:SIMIX_request_get_result(ctx->syscall_id));
90     smx_current_context = old_context;
91   }
92   xbt_dynar_reset(processes);
93 }
94