Logo AND Algorithmique Numérique Distribuée

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