Logo AND Algorithmique Numérique Distribuée

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