Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a580cb38ad480c09a2a5736fd306d86a005b3ae1
[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 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ruby);
17
18 static smx_context_t
19 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
20     void_f_pvoid_t cleanup_func,void *cleanup_arg);
21
22 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
23 static void smx_ctx_ruby_free(smx_context_t context);
24 static void smx_ctx_ruby_start(smx_context_t context);
25 static void smx_ctx_ruby_stop(smx_context_t context);
26 static void smx_ctx_ruby_suspend(smx_context_t context);
27 static void 
28 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
29 static void smx_ctx_ruby_wrapper(void); 
30
31
32 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory) {
33   *factory = xbt_new0(s_smx_context_factory_t,1);
34
35   (*factory)->create_context = smx_ctx_ruby_create_context;
36   (*factory)->finalize = smx_ctx_ruby_factory_finalize;
37   (*factory)->free = smx_ctx_ruby_free;
38   (*factory)->start = smx_ctx_ruby_start;
39   (*factory)->stop = smx_ctx_ruby_stop;
40   (*factory)->suspend = smx_ctx_ruby_suspend;
41   (*factory)->resume = smx_ctx_ruby_resume;
42   (*factory)->name = "smx_ruby_context_factory";
43   ruby_init();
44   ruby_init_loadpath();
45 }
46
47 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) {
48   free(*factory);
49   *factory = NULL;
50   return 0;
51 }
52
53 static smx_context_t 
54 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
55     void_f_pvoid_t cleanup_func,void* cleanup_arg) {
56
57   smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
58
59   /* if the user provided a function for the process , then use it
60      Otherwise it's the context for maestro */
61   if (code) {
62     context->cleanup_func = cleanup_func;
63     context->cleanup_arg = cleanup_arg;
64     context->process = (VALUE)code;
65     context->argc=argc;
66     context->argv=argv;
67
68     DEBUG1("smx_ctx_ruby_create_context(%s)...Done",argv[0]);
69   }
70   return (smx_context_t) context;
71 }
72
73 static void smx_ctx_ruby_free(smx_context_t context) {
74   /* VALUE process;
75   if (context)
76   {
77    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
78
79    if (ctx_ruby->process){
80      // if the Ruby Process is Alive , Join it   
81    // if ( process_isAlive(ctx_ruby->process))
82     {
83       process = ctx_ruby->process;
84       ctx_ruby->process = Qnil;
85       process_join(process);
86     } 
87
88   }
89   free(context);
90   context = NULL; 
91   }*/
92   DEBUG1("smx_ctx_ruby_free_context(%s)",context->argv[0]);
93   free (context);
94   context = NULL;
95 }
96
97 static void smx_ctx_ruby_start(smx_context_t context) {
98   DEBUG1("smx_ctx_ruby_start(%s) (nothing to do)",context->argv[0]);
99   /* Already Done .. Since a Ruby process is launched within initialization
100      We Start it Within the Initializer ... We Use the Semaphore To Keep
101      the thread alive waiting for mutex signal to execute the main*/
102 }
103
104 static void smx_ctx_ruby_stop(smx_context_t context) {
105   DEBUG1("smx_ctx_ruby_stop(%s)",context->argv[0]);
106
107   VALUE process = Qnil;
108   smx_ctx_ruby_t ctx_ruby,current;
109
110   if ( context->cleanup_func)
111     (*(context->cleanup_func)) (context->cleanup_arg);
112
113   ctx_ruby = (smx_ctx_ruby_t) context;
114
115   // Well , Let's Do The Same as JNI Stoppin' Process
116   if ( simix_global->current_process->iwannadie ) {
117     if( ctx_ruby->process ) {
118       //if the Ruby Process still Alive ,let's Schedule it
119       if ( rb_process_isAlive( ctx_ruby->process ) ) {
120         current = (smx_ctx_ruby_t)simix_global->current_process->context;
121         rb_process_schedule(current->process);
122         process = ctx_ruby->process;
123         // interupt/kill The Ruby Process
124         rb_process_kill_up(process);
125       }
126     }
127   } else {
128     process = ctx_ruby->process;
129     ctx_ruby->process = Qnil;
130   }
131   DEBUG1("smx_ctx_ruby_stop(%s)...Done",context->argv[0]);
132 }
133
134 static void smx_ctx_ruby_suspend(smx_context_t context) {
135
136     DEBUG1("smx_ctx_ruby_suspend(%s)",context->argv[0]);
137     smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
138     if (ctx_ruby->process)
139       rb_process_unschedule(ctx_ruby->process);
140 }
141
142 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) {
143   DEBUG2("smx_ctx_ruby_resume(%s,%s)",
144       (old_context->argc?old_context->argv[0]:"maestro"),
145       (new_context->argc?new_context->argv[0]:"maestro"));
146
147   smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
148   rb_process_schedule(ctx_ruby->process);
149
150 //  DEBUG1("smx_ctx_ruby_schedule(%s)...Done",
151 //      (new_context->argc?new_context->argv[0]:"maestro"));
152 }
153