Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
e6df224d29b87b422913fcd1e0eafd4a9ca89c11
[simgrid.git] / src / bindings / ruby / rb_msg_process.c
1 /*
2  * Copyright 2010, The SimGrid Team. All right reserved.
3  *
4  * This program is free software; you can redistribute 
5  * it and/or modify it under the terms of the license 
6  *(GNU LGPL) which comes with this package. 
7  */
8
9 #include "bindings/ruby_bindings.h"
10
11 #define DEBUG
12 // Init Ruby
13 void initRuby(void) {
14   ruby_init();
15   ruby_init_loadpath();
16   rb_require("RubyProcess.rb");
17 }
18
19
20 /*
21  * Functions for Ruby Process Management (Up Calls)
22  */
23
24
25 // get Ruby Process Name
26 VALUE rb_process_getName(VALUE ruby_process) {
27   initRuby();
28   // instance = rb_funcall3(rb_const_get(rb_cObject, rb_intern("RbProcess")),  rb_intern("new"), 0, 0);
29   return rb_funcall(ruby_process,rb_intern("getName"),0);
30
31 }
32
33 // Get  Process ID
34 static VALUE process_getID(VALUE ruby_process)
35 {
36
37   initRuby();
38   return rb_funcall(ruby_process,rb_intern("getID"),0);
39
40 }
41
42 // Get Bind
43 static VALUE process_getBind(VALUE ruby_process)
44 {
45
46   initRuby();
47   return rb_funcall(ruby_process,rb_intern("getBind"),0);
48
49 }
50
51
52 // Set Bind
53 static void process_setBind(VALUE ruby_process,long bind)
54 {
55
56   initRuby();
57   VALUE r_bind = LONG2FIX(bind);
58   rb_funcall(ruby_process,rb_intern("setBind"),1,r_bind);
59
60 }
61
62 // isAlive
63 static VALUE process_isAlive(VALUE ruby_process)
64 {
65
66   initRuby();
67   return rb_funcall(ruby_process,rb_intern("alive?"),0);
68
69 }
70
71 // Kill Process
72 static void process_kill(VALUE ruby_process)
73 {
74
75   initRuby();  
76   rb_funcall(ruby_process,rb_intern("kill"),0);
77
78 }
79
80 // join Process
81 static void process_join( VALUE ruby_process )
82 {
83
84   initRuby();
85   rb_funcall(ruby_process,rb_intern("join"),0);
86
87 }
88
89 // unschedule Process
90 static void process_unschedule( VALUE ruby_process )
91 {
92
93   initRuby();
94   rb_funcall(ruby_process,rb_intern("unschedule"),0);
95
96 }
97
98 // schedule Process
99 static void process_schedule( VALUE ruby_process )
100 {
101
102   initRuby();
103   rb_funcall(ruby_process,rb_intern("schedule"),0);
104
105 }
106
107 /***************************************************
108
109 Function for Native Process ( Bound ) Management
110
111 Methods Belong to MSG Module
112
113  ****************************************************/
114
115 // Process To Native
116
117 static m_process_t process_to_native(VALUE ruby_process)
118 {
119
120   VALUE id = process_getBind(ruby_process);
121   if (!id)
122   {
123     rb_raise(rb_eRuntimeError,"Process Not Bound >>> id_Bind Null");
124     return NULL;
125   }
126   long l_id= FIX2LONG(id);
127   return (m_process_t)l_id;
128
129 }
130
131 // Bind Process
132
133 static void processBind(VALUE ruby_process,m_process_t process)
134 {
135
136   long bind = (long)(process);
137   process_setBind(ruby_process,bind);
138
139 }
140
141
142 // processCreate
143
144 static void processCreate(VALUE class,VALUE ruby_process,VALUE host)
145 {
146
147   VALUE rbName;      // Name of Java Process instance
148   m_process_t process; // Native Process to Create
149   const char * name ; // Name of C Native Process
150   char alias[MAX_ALIAS_NAME + 1 ] = {0};
151   msg_mailbox_t mailbox;
152   rbName = process_getName(ruby_process);
153
154   if(!rbName) {
155     rb_raise(rb_eRuntimeError,"Internal error : Process Name Cannot be NULL");
156     return;
157   }
158   // Allocate the data for the simulation
159   process = xbt_new0(s_m_process_t,1);
160   process->simdata = xbt_new0(s_simdata_process_t,1);
161   // Do we Really Need to Create Ruby Process Instance , >> process is already a Ruby Process !! So..Keep on ;)
162   // Bind The Ruby Process instance to The Native Process
163   processBind(ruby_process,process);
164   name = RSTRING(rbName)->ptr;
165   process->name = xbt_strdup(name);
166   Data_Get_Struct(host,m_host_t,process->simdata->m_host);
167
168   if(!(process->simdata->m_host)) // Not Binded
169   {
170     free(process->simdata);
171     free(process->data);
172     free(process);
173     rb_raise(rb_eRuntimeError,"Host not bound...while creating native process");
174     return;
175   }
176   process->simdata->PID = msg_global->PID++; //  msg_global ??
177
178 #ifdef DEBUG
179   printf("fill in process %s/%s (pid=%d) %p (sd%=%p , host=%p, host->sd=%p)\n",
180       process->name , process->simdata->m_host->name,process->simdata->PID,
181       process,process->simdata, process->simdata->m_host,
182       process->simdata->m_host->simdata);
183 #endif
184   process->simdata->s_process =
185       SIMIX_process_create(process->name,
186           (xbt_main_func_t)ruby_process,
187           (void *) process,
188           process->simdata->m_host->simdata->smx_host->name,
189           0,NULL,NULL);
190
191 #ifdef DEBUG
192   printf("context created (s_process=%p)\n",process->simdata->s_process);
193 #endif
194   if (SIMIX_process_self()) { // SomeOne Created Me !!
195     process->simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data);
196   }
197   else
198   {
199     process->simdata->PPID = -1;
200   }
201   process->simdata->last_errno = MSG_OK;
202   // let's Add the Process to the list of the Simulation's Processes
203   xbt_fifo_unshift(msg_global->process_list,process);
204   sprintf(alias,"%s:%s",(process->simdata->m_host->simdata->smx_host)->name,
205       process->name);
206
207   mailbox = MSG_mailbox_new(alias);
208
209 }
210
211
212 // Process Management
213
214 static void processSuspend(VALUE class,VALUE ruby_process)
215 {
216
217   m_process_t process = process_to_native(ruby_process);
218
219   if (!process)
220   {
221     rb_raise(rb_eRuntimeError,"Process Not Bound...while suspending process");
222     return;  
223   }
224
225   // Trying to suspend The Process
226
227   if ( MSG_OK != MSG_process_suspend(process))
228     rb_raise(rb_eRuntimeError,"MSG_process_suspend() failed");
229
230
231 }
232
233 static void processResume(VALUE class,VALUE ruby_process)
234 {
235   m_process_t process = process_to_native(ruby_process);
236   if (!process)
237   {
238     rb_raise(rb_eRuntimeError,"Process not Bound...while resuming process");
239     return ;
240   }
241   // Trying to resume the process
242   if ( MSG_OK != MSG_process_resume(process))
243     rb_raise(rb_eRuntimeError,"MSG_process_resume() failed");
244
245 }
246
247 static VALUE processIsSuspend(VALUE class,VALUE ruby_process)
248 {
249
250   m_process_t process = process_to_native(ruby_process);
251   if (!process)
252   {
253     rb_raise (rb_eRuntimeError,"Process not Bound...while testing if suspended");
254     return;
255   }
256
257   // 1 is The Process is Suspended , 0 Otherwise
258   if(MSG_process_is_suspended(process))
259     return Qtrue;
260
261   return Qfalse;
262
263 }
264
265 static void processKill(VALUE class,VALUE ruby_process)
266 {
267   m_process_t process = process_to_native(ruby_process);
268
269   if(!process)
270   {
271     rb_raise (rb_eRuntimeError,"Process Not Bound...while killing process");
272     return ;
273   }
274   // Delete The Global Reference / Ruby Process
275   process_kill(ruby_process);
276   // Delete the Native Process
277   MSG_process_kill(process);
278
279 }
280
281 static VALUE processGetHost(VALUE class,VALUE ruby_process)
282 {
283
284   m_process_t process = process_to_native(ruby_process);
285   m_host_t host;
286
287   if (!process)
288   {
289     rb_raise(rb_eRuntimeError,"Process Not Bound...while getting Host");
290     return Qnil; // NULL
291   }
292
293   host = MSG_process_get_host(process);
294
295   if(!host->data)
296   {
297     rb_raise (rb_eRuntimeError,"MSG_process_get_host() failed");
298     return Qnil;
299   }
300
301   return Data_Wrap_Struct(class, 0, host_free, host);
302
303 }
304
305 static void processExit(VALUE class,VALUE ruby_process)
306 {
307
308   m_process_t process = process_to_native(ruby_process);
309   if(!process)
310   {
311     rb_raise(rb_eRuntimeError,"Process Not Bound...while exiting process");
312     return;
313   }
314   SIMIX_context_stop(SIMIX_process_self()->context);
315
316 }