Logo AND Algorithmique Numérique Distribuée

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