3 /* context_Ruby - implementation of context switching with lua coroutines */
5 /* Copyright (c) 2004-2008 the SimGrid team. All right reserved */
7 /* This program is free software; you can redistribute it and/or modify it
8 * under the terms of the license (GNU LGPL) which comes with this package. */
13 #include "xbt/function_types.h"
14 #include "xbt/sysdep.h"
16 #include "xbt/asserts.h"
17 #include "context_sysv_config.h"
18 #include "bindings/ruby/rb_msg_process.c"
19 // #include "bindings/ruby/rb_msg.c"
24 typedef struct s_smx_ctx_ruby
28 VALUE process; // The Ruby Process Instance
30 }s_smx_ctx_ruby_t,*smx_ctx_ruby_t;
33 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
34 void_f_pvoid_t cleanup_func,void *cleanup_arg);
36 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
38 static void smx_ctx_ruby_free(smx_context_t context);
40 static void smx_ctx_ruby_start(smx_context_t context);
42 static void smx_ctx_ruby_stop(smx_context_t context);
44 static void smx_ctx_ruby_suspend(smx_context_t context);
47 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
49 static void smx_ctx_ruby_wrapper(void);
53 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory)
56 *factory = xbt_new0(s_smx_context_factory_t,1);
58 (*factory)->create_context = smx_ctx_ruby_create_context;
59 (*factory)->finalize = smx_ctx_ruby_factory_finalize;
60 (*factory)->free = smx_ctx_ruby_free;
61 (*factory)->start = smx_ctx_ruby_start;
62 (*factory)->stop = smx_ctx_ruby_stop;
63 (*factory)->suspend = smx_ctx_ruby_suspend;
64 (*factory)->resume = smx_ctx_ruby_resume;
65 (*factory)->name = "smx_ruby_context_factory";
69 printf("SIMIX_ctx_ruby_factory_init...Done\n");
73 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory)
83 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
84 void_f_pvoid_t cleanup_func,void* cleanup_arg)
87 smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
89 /*if the user provided a function for the process , then use it
90 Otherwise it's the context for maestro */
93 context->cleanup_func = cleanup_func;
94 context->cleanup_arg = cleanup_arg;
95 context->process = (VALUE)code;
98 printf("smx_ctx_ruby_create_context...Done\n");
102 return (smx_context_t) context;
106 static void smx_ctx_ruby_free(smx_context_t context)
111 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
113 if (ctx_ruby->process){
114 // if the Ruby Process is Alive , Join it
115 // if ( process_isAlive(ctx_ruby->process))
117 process = ctx_ruby->process;
118 ctx_ruby->process = Qnil;
119 process_join(process);
129 printf("smx_ctx_ruby_free_context...Done\n");
134 static void smx_ctx_ruby_start(smx_context_t context)
137 /* Already Done .. Since a Ruby Process is launched within initialization
138 We Start it Within the Initializer ... We Use the Semaphore To Keep
139 The Thread Alive Waitin' For Mutex Signal to Execute The Main*/
143 static void smx_ctx_ruby_stop(smx_context_t context)
147 VALUE process = Qnil;
148 smx_ctx_ruby_t ctx_ruby,current;
150 if ( context->cleanup_func)
151 (*(context->cleanup_func)) (context->cleanup_arg);
153 ctx_ruby = (smx_ctx_ruby_t) context;
155 // Well , Let's Do The Same as JNI Stoppin' Process
156 if ( simix_global->current_process->iwannadie )
158 if( ctx_ruby->process )
160 //if the Ruby Process still Alive ,let's Schedule it
161 if ( process_isAlive( ctx_ruby->process ) )
163 current = (smx_ctx_ruby_t)simix_global->current_process->context;
164 process_schedule(current->process);
165 process = ctx_ruby->process;
166 // interupt/kill The Ruby Process
167 process_kill(process);
172 process = ctx_ruby->process;
173 ctx_ruby->process = Qnil;
177 printf("smx_ctx_ruby_stop...Done\n");
181 static void smx_ctx_ruby_suspend(smx_context_t context)
186 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
187 if (ctx_ruby->process)
188 process_unschedule( ctx_ruby->process ) ;
190 printf("smx_ctx_ruby_unschedule...Done\n");
195 rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
199 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context)
202 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
203 process_schedule(ctx_ruby->process);
206 printf("smx_ctx_ruby_schedule...Done\n");