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. */
11 #include "xbt/function_types.h"
12 #include "xbt/sysdep.h"
14 #include "xbt/asserts.h"
15 #include "context_sysv_config.h"
16 #include "bindings/ruby/rb_msg_process.c"
17 // #include "bindings/ruby/rb_msg.c"
22 typedef struct s_smx_ctx_ruby
26 VALUE process; // The Ruby Process Instance
28 }s_smx_ctx_ruby_t,*smx_ctx_ruby_t;
31 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
32 void_f_pvoid_t cleanup_func,void *cleanup_arg);
34 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
36 static void smx_ctx_ruby_free(smx_context_t context);
38 static void smx_ctx_ruby_start(smx_context_t context);
40 static void smx_ctx_ruby_stop(smx_context_t context);
42 static void smx_ctx_ruby_suspend(smx_context_t context);
45 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
47 static void smx_ctx_ruby_wrapper(void);
51 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory)
54 *factory = xbt_new0(s_smx_context_factory_t,1);
56 (*factory)->create_context = smx_ctx_ruby_create_context;
57 (*factory)->finalize = smx_ctx_ruby_factory_finalize;
58 (*factory)->free = smx_ctx_ruby_free;
59 (*factory)->start = smx_ctx_ruby_start;
60 (*factory)->stop = smx_ctx_ruby_stop;
61 (*factory)->suspend = smx_ctx_ruby_suspend;
62 (*factory)->resume = smx_ctx_ruby_resume;
63 (*factory)->name = "smx_ruby_context_factory";
67 printf("SIMIX_ctx_ruby_factory_init...Done\n");
71 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory)
81 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
82 void_f_pvoid_t cleanup_func,void* cleanup_arg)
85 smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
87 /*if the user provided a function for the process , then use it
88 Otherwise it's the context for maestro */
91 context->cleanup_func = cleanup_func;
92 context->cleanup_arg = cleanup_arg;
93 context->process = (VALUE)code;
96 printf("smx_ctx_ruby_create_context...Done\n");
100 return (smx_context_t) context;
104 static void smx_ctx_ruby_free(smx_context_t context)
109 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
111 if (ctx_ruby->process){
112 // if the Ruby Process is Alive , Join it
113 // if ( process_isAlive(ctx_ruby->process))
115 process = ctx_ruby->process;
116 ctx_ruby->process = Qnil;
117 process_join(process);
127 printf("smx_ctx_ruby_free_context...Done\n");
132 static void smx_ctx_ruby_start(smx_context_t context)
135 /* Already Done .. Since a Ruby Process is launched within initialization
136 We Start it Within the Initializer ... We Use the Semaphore To Keep
137 The Thread Alive Waitin' For Mutex Signal to Execute The Main*/
141 static void smx_ctx_ruby_stop(smx_context_t context)
145 VALUE process = Qnil;
146 smx_ctx_ruby_t ctx_ruby,current;
148 if ( context->cleanup_func)
149 (*(context->cleanup_func)) (context->cleanup_arg);
151 ctx_ruby = (smx_ctx_ruby_t) context;
153 // Well , Let's Do The Same as JNI Stoppin' Process
154 if ( simix_global->current_process->iwannadie )
156 if( ctx_ruby->process )
158 //if the Ruby Process still Alive ,let's Schedule it
159 if ( process_isAlive( ctx_ruby->process ) )
161 current = (smx_ctx_ruby_t)simix_global->current_process->context;
162 process_schedule(current->process);
163 process = ctx_ruby->process;
164 // interupt/kill The Ruby Process
165 process_kill(process);
170 process = ctx_ruby->process;
171 ctx_ruby->process = Qnil;
175 printf("smx_ctx_ruby_stop...Done\n");
179 static void smx_ctx_ruby_suspend(smx_context_t context)
184 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
185 if (ctx_ruby->process)
186 process_unschedule( ctx_ruby->process ) ;
188 printf("smx_ctx_ruby_unschedule...Done\n");
193 rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
197 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context)
200 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
201 process_schedule(ctx_ruby->process);
204 printf("smx_ctx_ruby_schedule...Done\n");