1 /* context_Ruby - implementation of context switching with/for ruby */
3 /* Copyright (c) 2010, the SimGrid team. All right reserved. */
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. */
9 #include "xbt/function_types.h"
10 #include "xbt/sysdep.h"
12 #include "xbt/asserts.h"
14 #include "bindings/ruby_bindings.h"
16 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ruby);
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);
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);
28 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
29 static void smx_ctx_ruby_wrapper(void);
32 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory) {
33 *factory = xbt_new0(s_smx_context_factory_t,1);
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";
47 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) {
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) {
57 smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
59 /* if the user provided a function for the process , then use it
60 Otherwise it's the context for maestro */
62 context->cleanup_func = cleanup_func;
63 context->cleanup_arg = cleanup_arg;
64 context->process = (VALUE)code;
68 DEBUG1("smx_ctx_ruby_create_context(%s)...Done",argv[0]);
70 return (smx_context_t) context;
73 static void smx_ctx_ruby_free(smx_context_t context) {
77 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
79 if (ctx_ruby->process){
80 // if the Ruby Process is Alive , Join it
81 // if ( process_isAlive(ctx_ruby->process))
83 process = ctx_ruby->process;
84 ctx_ruby->process = Qnil;
85 process_join(process);
92 DEBUG1("smx_ctx_ruby_free_context(%s)",context->argv[0]);
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*/
104 static void smx_ctx_ruby_stop(smx_context_t context) {
105 DEBUG1("smx_ctx_ruby_stop(%s)",context->argv[0]);
107 VALUE process = Qnil;
108 smx_ctx_ruby_t ctx_ruby,current;
110 if ( context->cleanup_func)
111 (*(context->cleanup_func)) (context->cleanup_arg);
113 ctx_ruby = (smx_ctx_ruby_t) context;
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);
128 process = ctx_ruby->process;
129 ctx_ruby->process = Qnil;
131 DEBUG1("smx_ctx_ruby_stop(%s)...Done",context->argv[0]);
134 static void smx_ctx_ruby_suspend(smx_context_t context) {
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);
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"));
147 smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
148 rb_process_schedule(ctx_ruby->process);
150 // DEBUG1("smx_ctx_ruby_schedule(%s)...Done",
151 // (new_context->argc?new_context->argv[0]:"maestro"));