Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7232 48e7efb5...
[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 }
46
47 static int smx_ctx_ruby_factory_finalize(smx_context_factory_t *factory) {
48   free(*factory);
49   *factory = NULL;
50   return 0;
51 }
52
53 static smx_context_t 
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) {
56
57   smx_ctx_ruby_t context = xbt_new0(s_smx_ctx_ruby_t,1);
58
59   /* if the user provided a function for the process , then use it
60      Otherwise it's the context for maestro */
61   if (code) {
62     context->cleanup_func = cleanup_func;
63     context->cleanup_arg = cleanup_arg;
64     context->process = (VALUE)code;
65     context->argc=argc;
66     context->argv=argv;
67
68     DEBUG1("smx_ctx_ruby_create_context(%s)...Done",argv[0]);
69   }
70   return (smx_context_t) context;
71 }
72
73 // FIXME 
74 static void smx_ctx_ruby_free(smx_context_t context) {
75  // DEBUG1("smx_ctx_ruby_free(%s)",context->argv[0]);
76   
77   //VALUE process;
78   /*if (context)
79   {
80    smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
81    rb_process_isProcess(ctx_ruby->process);
82    if (ctx_ruby->process){
83      // if the Ruby Process is Alive , Join it   
84     if ( rb_process_isAlive(ctx_ruby->process))
85     {
86       process = ctx_ruby->process;
87       ctx_ruby->process = Qnil;
88       rb_process_join(process);
89     } 
90   }
91   free(context);
92   context = NULL; 
93   } */
94  
95  if (context) {
96     DEBUG1("smx_ctx_ruby_free_context(%p)",context);
97     free (context);
98     context = NULL;
99   }
100 }
101
102 static void smx_ctx_ruby_start(smx_context_t context) {
103   DEBUG1("smx_ctx_ruby_start(%s) (nothing to do)",context->argv[0]);
104   /* Already Done .. Since a Ruby process is launched within initialization
105      We Start it Within the Initializer ... We Use the Semaphore To Keep
106      the thread alive waiting for mutex signal to execute the main*/
107 }
108
109 static void smx_ctx_ruby_stop(smx_context_t context) {
110   DEBUG0("smx_ctx_ruby_stop()");
111   VALUE process = Qnil;
112   smx_ctx_ruby_t ctx_ruby,current;
113
114   if ( context->cleanup_func)
115     (*(context->cleanup_func)) (context->cleanup_arg);
116
117   ctx_ruby = (smx_ctx_ruby_t) context;
118   
119   if ( simix_global->current_process->iwannadie ) {
120     if( ctx_ruby->process ) {
121       
122       //if the Ruby Process still Alive ,let's Schedule it
123       if ( rb_process_isAlive( ctx_ruby->process ) ) {
124
125         current = (smx_ctx_ruby_t)simix_global->current_process->context;       
126         rb_process_schedule(current->process);
127         process = ctx_ruby->process;
128         // interupt/kill The Ruby Process
129         rb_process_kill_up(process);
130       }
131     }
132   } else {
133
134     if (ctx_ruby->process) 
135      ctx_ruby->process = Qnil;
136
137   }
138 }
139
140 static void smx_ctx_ruby_suspend(smx_context_t context) {
141
142     DEBUG1("smx_ctx_ruby_suspend(%s)",context->argv[0]);
143     smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
144     if (ctx_ruby->process)
145       rb_process_unschedule(ctx_ruby->process);
146 }
147
148 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) {
149   DEBUG2("smx_ctx_ruby_resume(%s,%s)",
150       (old_context->argc?old_context->argv[0]:"maestro"),
151       (new_context->argc?new_context->argv[0]:"maestro"));
152
153   smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
154   rb_process_schedule(ctx_ruby->process);
155
156 }