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 "context_sysv_config.h"
14 typedef struct s_smx_ctx_ruby
17 VALUE process; // The Process Ruby Instance
19 }s_smx_ctx_ruby_t,*smx_ctx_ruby_t;
22 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
23 void_f_pvoid_t cleanup_func,void *cleanup_arg);
26 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
28 static void smx_ctx_ruby_free(smx_context_t context);
30 static void smx_ctx_ruby_start(smx_context_t context);
32 static void smx_ctx_ruby_stop(smx_context_t context);
34 static void smx_ctx_ruby_suspend(smx_context_t context);
37 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
39 static void smx_ctx_ruby_wrapper(void); //??!!
43 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory)
46 *factory = xbt_new0(s_smx_context_factory_t,1);
48 (*factory)->create_context = smx_ctx_ruby_create_context;
49 (*factory)->finalize = smx_ctx_ruby_factory_finalize;
50 (*factory)->free = smx_ctx_ruby_free;
51 (*factory)->start = smx_ctx_ruby_start;
52 (*factory)->stop = smx_ctx_ruby_stop;
53 (*factory)->suspend = smx_ctx_ruby_suspend;
54 (*factory)->resume = smx_ctx_ruby_resume;
55 (*factory)->name = "smx_ruby_context_factory";
62 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory)
72 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
73 void_f_pvoid_t cleanup_func,void* cleanup_arg)
76 smx_ctx_ruby_t context = xbt_new0(s_smx_ruby_t,1);
78 /*if the user provided a function for the process , then use it
79 Otherwise it's the context for maestro */
82 context->cleanup_func = cleanup_func;
83 context->cleanup_arg = cleanup_arg;
84 context->process = rb_funcall3(rb_const_get(rb_cObject, rb_intern("RbProcess")), rb_intern("new"), 0, 0);
85 //context->process = rb_thread_main(); // Or VALUE rb_thread_create ( VALUE(*(ANYARGS), void *) )
89 return (smx_context_t) context;
93 static void smx_ctx_ruby_free(smx_context_t context)
98 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
100 if (ctx_ruby->process)
101 VALUE process = ctx_ruby->process;
103 ctx_ruby->process = Qnil;
105 // if the Ruby Process is Alive , Join it
107 if ( process_isAlive(process) )
108 process_join(process);
122 static void smx_ctx_ruby_start(smx_context_t context)
130 static void smx_ctx_ruby_stop(smx_context_t context)
133 VALUE process = Qnil;
134 smx_ctx_ruby_t ctx_ruby;
136 if ( context->cleanup_func)
137 (*(context->cleanup_func)) (context->cleanup_arg);
139 ctx_ruby = (smx_ctx_ruby_t) context;
141 // Well , Let's Do The Same as JNI Stoppin' Process
142 if ( simix_gloabl->current_process->iwannadie )
144 if( ctx_ruby->process )
146 //if the Ruby Process still Alive ,let's Schedule it
147 if ( process_isAlive( ctx_ruby->process ) )
150 current = (smx_ctx_ruby_t)simix_gloabl->current_process->context:
151 process_schedule(current->process);
153 process = ctx_ruby->process;
155 // interupt/kill The Ruby Process
156 process_kill(process);
162 process = ctx_ruby->process;
163 ctx_ruby->process = Qnil;
170 static void smx_ctx_ruby_suspend(smx_context_t context)
175 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
176 if (ctx_ruby->process)
177 process_unschedule( ctx_ruby->process ) ;
181 rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
185 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context)
188 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
190 process_schedule( ctx_ruby->process );