Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
0dc94daaa2d517e499a753bd281dc8dc3808d823
[simgrid.git] / src / simix / smx_context_ruby.c
1 /* context_Ruby - implementation of context switching with/for ruby         */
2
3 /* Copyright (c) 2010, the SimGrid team. All right reserved.                */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "private.h"
9 #include "xbt/function_types.h"
10 #include "xbt/sysdep.h"
11 #include "xbt/log.h"
12 #include "xbt/asserts.h"
13
14 #include "bindings/ruby_bindings.h"
15
16 static smx_context_t
17 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
18     void_f_pvoid_t cleanup_func,void *cleanup_arg);
19
20 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
21 static void smx_ctx_ruby_free(smx_context_t context);
22 static void smx_ctx_ruby_start(smx_context_t context);
23 static void smx_ctx_ruby_stop(smx_context_t context);
24 static void smx_ctx_ruby_suspend(smx_context_t context);
25 static void 
26 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
27 static void smx_ctx_ruby_wrapper(void); 
28
29
30 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory) {
31   *factory = xbt_new0(s_smx_context_factory_t,1);
32
33   (*factory)->create_context = smx_ctx_ruby_create_context;
34   (*factory)->finalize = smx_ctx_ruby_factory_finalize;
35   (*factory)->free = smx_ctx_ruby_free;
36   (*factory)->start = smx_ctx_ruby_start;
37   (*factory)->stop = smx_ctx_ruby_stop;
38   (*factory)->suspend = smx_ctx_ruby_suspend;
39   (*factory)->resume = smx_ctx_ruby_resume;
40   (*factory)->name = "smx_ruby_context_factory";
41   ruby_init();
42   ruby_init_loadpath();
43   DEBUG0("SIMIX_ctx_ruby_factory_init...Done");
44 }
45
46 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) {
47   free(*factory);
48   *factory = NULL;
49   return 0;
50 }
51
52 static smx_context_t 
53 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
54     void_f_pvoid_t cleanup_func,void* cleanup_arg) {
55
56   smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
57
58   /*if the user provided a function for the process , then use it 
59   Otherwise it's the context for maestro */
60   if (code) {
61     context->cleanup_func = cleanup_func;
62     context->cleanup_arg = cleanup_arg;
63     context->process = (VALUE)code;
64
65     DEBUG0("smx_ctx_ruby_create_context...Done");
66   }
67   return (smx_context_t) context;
68 }
69
70 static void smx_ctx_ruby_free(smx_context_t context) {
71   /* VALUE process;
72   if (context)
73   {
74    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
75
76    if (ctx_ruby->process){
77      // if the Ruby Process is Alive , Join it   
78    // if ( process_isAlive(ctx_ruby->process))
79     {
80       process = ctx_ruby->process;
81       ctx_ruby->process = Qnil;
82       process_join(process);
83     } 
84
85   }
86   free(context);
87   context = NULL; 
88   }*/
89   free (context);
90   context = NULL;
91   DEBUG0("smx_ctx_ruby_free_context...Done");
92 }
93
94 static void smx_ctx_ruby_start(smx_context_t context) {
95   /* Already Done .. Since a Ruby Process is launched within initialization
96  We Start it Within the Initializer ... We Use the Semaphore To Keep 
97  The Thread Alive Waitin' For Mutex Signal to Execute The Main*/
98
99 }
100
101 static void smx_ctx_ruby_stop(smx_context_t context) {
102
103   VALUE process = Qnil;
104   smx_ctx_ruby_t ctx_ruby,current;
105
106   if ( context->cleanup_func)
107     (*(context->cleanup_func)) (context->cleanup_arg);
108
109   ctx_ruby = (smx_ctx_ruby_t) context;
110
111   // Well , Let's Do The Same as JNI Stoppin' Process
112   if ( simix_global->current_process->iwannadie ) {
113     if( ctx_ruby->process ) {
114       //if the Ruby Process still Alive ,let's Schedule it
115       if ( rb_process_isAlive( ctx_ruby->process ) ) {
116         current = (smx_ctx_ruby_t)simix_global->current_process->context;
117         rb_process_schedule(current->process);
118         process = ctx_ruby->process;
119         // interupt/kill The Ruby Process
120         rb_process_kill_up(process);
121       }
122     }
123   } else {
124     process = ctx_ruby->process;
125     ctx_ruby->process = Qnil;
126   }
127   DEBUG0("smx_ctx_ruby_stop...Done\n");
128 }
129
130 static void smx_ctx_ruby_suspend(smx_context_t context) {
131
132   if (context) {
133     smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
134     if (ctx_ruby->process)
135       rb_process_unschedule(ctx_ruby->process);
136     DEBUG0("smx_ctx_ruby_unschedule...Done");
137   } else
138     rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
139 }
140
141 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) {
142   smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
143   rb_process_schedule(ctx_ruby->process);
144
145   DEBUG0("smx_ctx_ruby_schedule...Done");
146 }
147