Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Try to fix the finalization process of ruby simulations. THE REST WORKS, yuhu
[simgrid.git] / src / simix / smx_context_ruby.c
1 /* context_Ruby - implementation of context switching with/for ruby         */
2
3 /* Copyright (c) 2010, the SimGrid team. All right reserved.                */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "private.h"
9 #include "xbt/function_types.h"
10 #include "xbt/sysdep.h"
11 #include "xbt/log.h"
12 #include "xbt/asserts.h"
13
14 #include "bindings/ruby_bindings.h"
15
16 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ruby);
17
18 static smx_context_t
19 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
20     void_f_pvoid_t cleanup_func,void *cleanup_arg);
21
22 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
23 static void smx_ctx_ruby_free(smx_context_t context);
24 static void smx_ctx_ruby_start(smx_context_t context);
25 static void smx_ctx_ruby_stop(smx_context_t context);
26 static void smx_ctx_ruby_suspend(smx_context_t context);
27 static void 
28 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
29 static void smx_ctx_ruby_wrapper(void); 
30
31
32 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory) {
33   *factory = xbt_new0(s_smx_context_factory_t,1);
34
35   (*factory)->create_context = smx_ctx_ruby_create_context;
36   (*factory)->finalize = smx_ctx_ruby_factory_finalize;
37   (*factory)->free = smx_ctx_ruby_free;
38   (*factory)->start = smx_ctx_ruby_start;
39   (*factory)->stop = smx_ctx_ruby_stop;
40   (*factory)->suspend = smx_ctx_ruby_suspend;
41   (*factory)->resume = smx_ctx_ruby_resume;
42   (*factory)->name = "smx_ruby_context_factory";
43   ruby_init();
44   ruby_init_loadpath();
45 }
46
47 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) {
48   free(*factory);
49   *factory = NULL;
50   return 0;
51 }
52
53 static smx_context_t 
54 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
55     void_f_pvoid_t cleanup_func,void* cleanup_arg) {
56
57   smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
58
59   /* if the user provided a function for the process , then use it
60      Otherwise it's the context for maestro */
61   if (code) {
62     context->cleanup_func = cleanup_func;
63     context->cleanup_arg = cleanup_arg;
64     context->process = (VALUE)code;
65     context->argc=argc;
66     context->argv=argv;
67
68     DEBUG1("smx_ctx_ruby_create_context(%s)...Done",argv[0]);
69   }
70   return (smx_context_t) context;
71 }
72
73 static void smx_ctx_ruby_free(smx_context_t context) {
74   /* VALUE process;
75   if (context)
76   {
77    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
78
79    if (ctx_ruby->process){
80      // if the Ruby Process is Alive , Join it   
81    // if ( process_isAlive(ctx_ruby->process))
82     {
83       process = ctx_ruby->process;
84       ctx_ruby->process = Qnil;
85       process_join(process);
86     } 
87
88   }
89   free(context);
90   context = NULL; 
91   }*/
92   if (context) {
93     DEBUG1("smx_ctx_ruby_free_context(%p)",context);
94     free (context);
95     context = NULL;
96   }
97 }
98
99 static void smx_ctx_ruby_start(smx_context_t context) {
100   DEBUG1("smx_ctx_ruby_start(%s) (nothing to do)",context->argv[0]);
101   /* Already Done .. Since a Ruby process is launched within initialization
102      We Start it Within the Initializer ... We Use the Semaphore To Keep
103      the thread alive waiting for mutex signal to execute the main*/
104 }
105
106 static void smx_ctx_ruby_stop(smx_context_t context) {
107   DEBUG0("smx_ctx_ruby_stop()");
108
109   VALUE process = Qnil;
110   smx_ctx_ruby_t ctx_ruby,current;
111
112   if ( context->cleanup_func)
113     (*(context->cleanup_func)) (context->cleanup_arg);
114
115   ctx_ruby = (smx_ctx_ruby_t) context;
116
117   // Well , Let's Do The Same as JNI Stoppin' Process
118   if ( simix_global->current_process->iwannadie ) {
119     if( ctx_ruby->process ) {
120       //if the Ruby Process still Alive ,let's Schedule it
121       if ( rb_process_isAlive( ctx_ruby->process ) ) {
122         current = (smx_ctx_ruby_t)simix_global->current_process->context;
123         rb_process_schedule(current->process);
124         process = ctx_ruby->process;
125         // interupt/kill The Ruby Process
126         rb_process_kill_up(process);
127       }
128     }
129   } else {
130     process = ctx_ruby->process;
131     ctx_ruby->process = Qnil;
132   }
133 }
134
135 static void smx_ctx_ruby_suspend(smx_context_t context) {
136
137     DEBUG1("smx_ctx_ruby_suspend(%s)",context->argv[0]);
138     smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
139     if (ctx_ruby->process)
140       rb_process_unschedule(ctx_ruby->process);
141 }
142
143 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) {
144   DEBUG2("smx_ctx_ruby_resume(%s,%s)",
145       (old_context->argc?old_context->argv[0]:"maestro"),
146       (new_context->argc?new_context->argv[0]:"maestro"));
147
148   smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
149   rb_process_schedule(ctx_ruby->process);
150
151 //  DEBUG1("smx_ctx_ruby_schedule(%s)...Done",
152 //      (new_context->argc?new_context->argv[0]:"maestro"));
153 }
154