3 /* context_Ruby - implementation of context switching with ruby coroutines */
5 /* Copyright (c) 2010, 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"
19 typedef struct s_smx_ctx_ruby
23 VALUE process; // The Ruby Process Instance
25 }s_smx_ctx_ruby_t,*smx_ctx_ruby_t;
28 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
29 void_f_pvoid_t cleanup_func,void *cleanup_arg);
31 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory);
33 static void smx_ctx_ruby_free(smx_context_t context);
35 static void smx_ctx_ruby_start(smx_context_t context);
37 static void smx_ctx_ruby_stop(smx_context_t context);
39 static void smx_ctx_ruby_suspend(smx_context_t context);
42 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
44 static void smx_ctx_ruby_wrapper(void);
48 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory)
51 *factory = xbt_new0(s_smx_context_factory_t,1);
53 (*factory)->create_context = smx_ctx_ruby_create_context;
54 (*factory)->finalize = smx_ctx_ruby_factory_finalize;
55 (*factory)->free = smx_ctx_ruby_free;
56 (*factory)->start = smx_ctx_ruby_start;
57 (*factory)->stop = smx_ctx_ruby_stop;
58 (*factory)->suspend = smx_ctx_ruby_suspend;
59 (*factory)->resume = smx_ctx_ruby_resume;
60 (*factory)->name = "smx_ruby_context_factory";
64 printf("SIMIX_ctx_ruby_factory_init...Done\n");
68 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory)
78 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
79 void_f_pvoid_t cleanup_func,void* cleanup_arg)
82 smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
84 /*if the user provided a function for the process , then use it
85 Otherwise it's the context for maestro */
88 context->cleanup_func = cleanup_func;
89 context->cleanup_arg = cleanup_arg;
90 context->process = (VALUE)code;
93 printf("smx_ctx_ruby_create_context...Done\n");
97 return (smx_context_t) context;
101 static void smx_ctx_ruby_free(smx_context_t context)
106 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
108 if (ctx_ruby->process){
109 // if the Ruby Process is Alive , Join it
110 // if ( process_isAlive(ctx_ruby->process))
112 process = ctx_ruby->process;
113 ctx_ruby->process = Qnil;
114 process_join(process);
124 printf("smx_ctx_ruby_free_context...Done\n");
129 static void smx_ctx_ruby_start(smx_context_t context)
132 /* Already Done .. Since a Ruby Process is launched within initialization
133 We Start it Within the Initializer ... We Use the Semaphore To Keep
134 The Thread Alive Waitin' For Mutex Signal to Execute The Main*/
138 static void smx_ctx_ruby_stop(smx_context_t context)
142 VALUE process = Qnil;
143 smx_ctx_ruby_t ctx_ruby,current;
145 if ( context->cleanup_func)
146 (*(context->cleanup_func)) (context->cleanup_arg);
148 ctx_ruby = (smx_ctx_ruby_t) context;
150 // Well , Let's Do The Same as JNI Stoppin' Process
151 if ( simix_global->current_process->iwannadie )
153 if( ctx_ruby->process )
155 //if the Ruby Process still Alive ,let's Schedule it
156 if ( process_isAlive( ctx_ruby->process ) )
158 current = (smx_ctx_ruby_t)simix_global->current_process->context;
159 process_schedule(current->process);
160 process = ctx_ruby->process;
161 // interupt/kill The Ruby Process
162 process_kill(process);
167 process = ctx_ruby->process;
168 ctx_ruby->process = Qnil;
172 printf("smx_ctx_ruby_stop...Done\n");
176 static void smx_ctx_ruby_suspend(smx_context_t context)
181 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
182 if (ctx_ruby->process)
183 process_unschedule( ctx_ruby->process ) ;
185 printf("smx_ctx_ruby_unschedule...Done\n");
190 rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
194 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context)
197 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
198 process_schedule(ctx_ruby->process);
201 printf("smx_ctx_ruby_schedule...Done\n");