Logo AND Algorithmique Numérique Distribuée

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