Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b5062bb60defe9ce273ba54f08e7da184a09d976
[simgrid.git] / src / simix / smx_context_ruby.c
1 /* $Id$ */
2
3 /* context_Ruby - implementation of context switching with ruby coroutines */
4
5 /* Copyright (c) 2010, the SimGrid team. All right reserved */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 #include "private.h"
11 #include "xbt/function_types.h"
12 #include "xbt/sysdep.h"
13 #include "xbt/log.h"
14 #include "xbt/asserts.h"
15
16 #include "bindings/ruby_bindings.h"
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
24 static void smx_ctx_ruby_free(smx_context_t context);
25
26 static void smx_ctx_ruby_start(smx_context_t context);
27
28 static void smx_ctx_ruby_stop(smx_context_t context);
29
30 static void smx_ctx_ruby_suspend(smx_context_t context);
31
32 static void 
33   smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
34
35 static void smx_ctx_ruby_wrapper(void); 
36
37
38
39 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory)
40 {
41   
42  *factory = xbt_new0(s_smx_context_factory_t,1);
43  
44  (*factory)->create_context = smx_ctx_ruby_create_context;
45  (*factory)->finalize = smx_ctx_ruby_factory_finalize;
46  (*factory)->free = smx_ctx_ruby_free;
47  (*factory)->start = smx_ctx_ruby_start;
48  (*factory)->stop = smx_ctx_ruby_stop;
49  (*factory)->suspend = smx_ctx_ruby_suspend;
50  (*factory)->resume = smx_ctx_ruby_resume;
51  (*factory)->name = "smx_ruby_context_factory";
52   ruby_init();
53   ruby_init_loadpath();
54   #ifdef MY_DEBUG
55   printf("SIMIX_ctx_ruby_factory_init...Done\n");
56   #endif 
57 }
58   
59 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory)
60 {
61   
62  free(*factory);
63  *factory = NULL;
64  return 0;
65  
66 }
67
68 static smx_context_t 
69   smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
70                               void_f_pvoid_t cleanup_func,void* cleanup_arg)
71 {
72   
73   smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
74   
75   /*if the user provided a function for the process , then use it 
76   Otherwise it's the context for maestro */
77   if( code )
78   {
79    context->cleanup_func = cleanup_func;
80    context->cleanup_arg = cleanup_arg;
81    context->process = (VALUE)code;
82    
83   #ifdef MY_DEBUG
84   printf("smx_ctx_ruby_create_context...Done\n");
85   #endif
86    
87   }
88   return (smx_context_t) context;
89   
90 }
91   
92 static void smx_ctx_ruby_free(smx_context_t context)
93 {
94  /* VALUE process;
95   if (context)
96   {
97    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
98    
99    if (ctx_ruby->process){
100      // if the Ruby Process is Alive , Join it   
101    // if ( process_isAlive(ctx_ruby->process))
102     {
103       process = ctx_ruby->process;
104       ctx_ruby->process = Qnil;
105       process_join(process);
106     } 
107     
108   }
109   free(context);
110   context = NULL; 
111   }*/
112   free (context);
113   context = NULL;
114     #ifdef MY_DEBUG
115   printf("smx_ctx_ruby_free_context...Done\n");
116   #endif
117   
118 }
119
120 static void smx_ctx_ruby_start(smx_context_t context)
121 {
122    
123  /* Already Done .. Since a Ruby Process is launched within initialization
124  We Start it Within the Initializer ... We Use the Semaphore To Keep 
125  The Thread Alive Waitin' For Mutex Signal to Execute The Main*/
126  
127 }
128
129 static void smx_ctx_ruby_stop(smx_context_t context)
130 {
131   
132   
133   VALUE process = Qnil;
134   smx_ctx_ruby_t ctx_ruby,current;
135   
136   if ( context->cleanup_func)
137     (*(context->cleanup_func)) (context->cleanup_arg);
138   
139   ctx_ruby = (smx_ctx_ruby_t) context;
140   
141   // Well , Let's Do The Same as JNI Stoppin' Process
142   if ( simix_global->current_process->iwannadie )
143   {
144    if( ctx_ruby->process )
145    {
146     //if the Ruby Process still Alive ,let's Schedule it
147     if ( rb_process_isAlive( ctx_ruby->process ) )
148     {
149      current = (smx_ctx_ruby_t)simix_global->current_process->context;
150      rb_process_schedule(current->process);
151      process = ctx_ruby->process;     
152      // interupt/kill The Ruby Process
153      rb_process_kill_up(process);
154     }
155    }    
156   }else {
157    
158     process = ctx_ruby->process;
159     ctx_ruby->process = Qnil;
160     
161   }
162   #ifdef MY_DEBUG
163   printf("smx_ctx_ruby_stop...Done\n");
164   #endif
165 }
166
167 static void smx_ctx_ruby_suspend(smx_context_t context)
168 {
169
170 if (context)
171 {
172 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
173   if (ctx_ruby->process)
174     rb_process_unschedule( ctx_ruby->process ) ;
175 #ifdef MY_DEBUG
176   printf("smx_ctx_ruby_unschedule...Done\n");
177 #endif
178 }
179   
180   else
181     rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
182   
183 }
184
185 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context)
186 {
187   
188  smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
189  rb_process_schedule(ctx_ruby->process);
190  
191   #ifdef MY_DEBUG
192     printf("smx_ctx_ruby_schedule...Done\n");
193   #endif
194  
195 }