Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Massive cleanups in ruby. Not yet working (segfault on task reception)
[simgrid.git] / src / simix / smx_context_ruby.c
1 /* context_Ruby - implementation of context switching with/for ruby         */
2
3 /* Copyright (c) 2010, the SimGrid team. All right reserved.                */
4
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. */
7
8 #include "private.h"
9 #include "xbt/function_types.h"
10 #include "xbt/sysdep.h"
11 #include "xbt/log.h"
12 #include "xbt/asserts.h"
13
14 #include "bindings/ruby_bindings.h"
15
16 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ruby);
17
18 static smx_context_t
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);
21
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);
27 static void 
28 smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context);
29 static void smx_ctx_ruby_wrapper(void); 
30
31
32 void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory) {
33   *factory = xbt_new0(s_smx_context_factory_t,1);
34
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";
43   ruby_init();
44   ruby_init_loadpath();
45   DEBUG0("SIMIX_ctx_ruby_factory_init...Done");
46 }
47
48 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) {
49   free(*factory);
50   *factory = NULL;
51   return 0;
52 }
53
54 static smx_context_t 
55 smx_ctx_ruby_create_context(xbt_main_func_t code,int argc,char** argv,
56     void_f_pvoid_t cleanup_func,void* cleanup_arg) {
57
58   smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
59
60   /*if the user provided a function for the process , then use it 
61   Otherwise it's the context for maestro */
62   if (code) {
63     context->cleanup_func = cleanup_func;
64     context->cleanup_arg = cleanup_arg;
65     context->process = (VALUE)code;
66
67     DEBUG0("smx_ctx_ruby_create_context...Done");
68   }
69   return (smx_context_t) context;
70 }
71
72 static void smx_ctx_ruby_free(smx_context_t context) {
73   /* VALUE process;
74   if (context)
75   {
76    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
77
78    if (ctx_ruby->process){
79      // if the Ruby Process is Alive , Join it   
80    // if ( process_isAlive(ctx_ruby->process))
81     {
82       process = ctx_ruby->process;
83       ctx_ruby->process = Qnil;
84       process_join(process);
85     } 
86
87   }
88   free(context);
89   context = NULL; 
90   }*/
91   free (context);
92   context = NULL;
93   DEBUG0("smx_ctx_ruby_free_context...Done");
94 }
95
96 static void smx_ctx_ruby_start(smx_context_t context) {
97   /* Already Done .. Since a Ruby Process is launched within initialization
98  We Start it Within the Initializer ... We Use the Semaphore To Keep 
99  The Thread Alive Waitin' For Mutex Signal to Execute The Main*/
100
101 }
102
103 static void smx_ctx_ruby_stop(smx_context_t context) {
104
105   VALUE process = Qnil;
106   smx_ctx_ruby_t ctx_ruby,current;
107
108   if ( context->cleanup_func)
109     (*(context->cleanup_func)) (context->cleanup_arg);
110
111   ctx_ruby = (smx_ctx_ruby_t) context;
112
113   // Well , Let's Do The Same as JNI Stoppin' Process
114   if ( simix_global->current_process->iwannadie ) {
115     if( ctx_ruby->process ) {
116       //if the Ruby Process still Alive ,let's Schedule it
117       if ( rb_process_isAlive( ctx_ruby->process ) ) {
118         current = (smx_ctx_ruby_t)simix_global->current_process->context;
119         rb_process_schedule(current->process);
120         process = ctx_ruby->process;
121         // interupt/kill The Ruby Process
122         rb_process_kill_up(process);
123       }
124     }
125   } else {
126     process = ctx_ruby->process;
127     ctx_ruby->process = Qnil;
128   }
129   DEBUG0("smx_ctx_ruby_stop...Done\n");
130 }
131
132 static void smx_ctx_ruby_suspend(smx_context_t context) {
133
134   if (context) {
135     smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
136     if (ctx_ruby->process)
137       rb_process_unschedule(ctx_ruby->process);
138     DEBUG0("smx_ctx_ruby_unschedule...Done");
139   } else
140     rb_raise(rb_eRuntimeError,"smx_ctx_ruby_suspend failed");
141 }
142
143 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) {
144   smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
145   rb_process_schedule(ctx_ruby->process);
146
147   DEBUG0("smx_ctx_ruby_schedule...Done");
148 }
149