Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
First version of ruby bindings by Medhi
[simgrid.git] / src / bindings / ruby / 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 "provate.h"
11 #include "xbt/function_types.h"
12 #include "context_sysv_config.h"
13
14 typedef struct s_smx_ctx_ruby
15 {
16   SMX_CTX_BASE_T;
17   VALUE process;   // The Process Ruby Instance 
18   //...
19 }s_smx_ctx_ruby_t,*smx_ctx_ruby_t;
20   
21 static smx_context_t
22 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
23                             void_f_pvoid_t cleanup_func,void *cleanup_arg);
24
25
26 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
27
28 static void smx_ctx_ruby_free(smx_context_t context);
29
30 static void smx_ctx_ruby_start(smx_context_t context);
31
32 static void smx_ctx_ruby_stop(smx_context_t context);
33
34 static void smx_ctx_ruby_suspend(smx_context_t context);
35
36 static void 
37   smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
38
39 static void smx_ctx_ruby_wrapper(void); //??!!
40
41
42
43 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory)
44 {
45   
46  *factory = xbt_new0(s_smx_context_factory_t,1);
47  
48  (*factory)->create_context = smx_ctx_ruby_create_context;
49  (*factory)->finalize = smx_ctx_ruby_factory_finalize;
50  (*factory)->free = smx_ctx_ruby_free;
51  (*factory)->start = smx_ctx_ruby_start;
52  (*factory)->stop = smx_ctx_ruby_stop;
53  (*factory)->suspend = smx_ctx_ruby_suspend;
54  (*factory)->resume = smx_ctx_ruby_resume;
55  (*factory)->name = "smx_ruby_context_factory";
56  
57   ruby_init();
58   ruby_init_loadpath();
59   
60 }
61   
62 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory)
63 {
64   
65  free(*factory);
66  *factory = NULL;
67  return 0;
68  
69 }
70
71 static smx_context_t 
72   smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
73                               void_f_pvoid_t cleanup_func,void* cleanup_arg)
74 {
75   
76   smx_ctx_ruby_t context = xbt_new0(s_smx_ruby_t,1);
77   
78   /*if the user provided a function for the process , then use it 
79   Otherwise it's the context for maestro */
80   if( code )
81   {
82    context->cleanup_func = cleanup_func;
83    context->cleanup_arg = cleanup_arg;
84    context->process = rb_funcall3(rb_const_get(rb_cObject, rb_intern("RbProcess")),  rb_intern("new"), 0, 0);
85    //context->process = rb_thread_main(); // Or VALUE rb_thread_create          (       VALUE(*(ANYARGS), void *)                ) 
86    
87    
88   }
89   return (smx_context_t) context;
90   
91 }
92   
93 static void smx_ctx_ruby_free(smx_context_t context)
94 {
95   
96   if (context)
97   {
98    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
99    
100    if (ctx_ruby->process)
101      VALUE process = ctx_ruby->process;
102     
103      ctx_ruby->process = Qnil;
104      
105      // if the Ruby Process is Alive , Join it  
106      
107     if ( process_isAlive(process) )
108       process_join(process);
109     
110   }
111   
112   free(context);
113   context = NULL;
114     
115     
116   }
117   
118   
119 }
120
121
122 static void smx_ctx_ruby_start(smx_context_t context)
123 {
124   
125   
126   
127 }
128
129
130 static void smx_ctx_ruby_stop(smx_context_t context)
131 {
132   
133   VALUE process = Qnil;
134   smx_ctx_ruby_t ctx_ruby;
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_gloabl->current_process->iwannadie )
143   {
144    if( ctx_ruby->process )
145    {
146     //if the Ruby Process still Alive ,let's Schedule it
147     if ( process_isAlive( ctx_ruby->process ) )
148     {
149      
150      current = (smx_ctx_ruby_t)simix_gloabl->current_process->context:
151      process_schedule(current->process); 
152       
153      process = ctx_ruby->process;
154      
155      // interupt/kill The Ruby Process
156      process_kill(process);
157       
158     }
159    }    
160   }else {
161    
162     process = ctx_ruby->process;
163     ctx_ruby->process = Qnil;
164     
165   }
166
167   
168 }
169
170 static void smx_ctx_ruby_suspend(smx_context_t context)
171 {
172
173 if ( context )
174 {
175 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
176   if (ctx_ruby->process)
177     process_unschedule( ctx_ruby->process ) ;
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  
190  process_schedule( ctx_ruby->process );
191   
192   
193 }