Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
added MPI_Get_processor_name()
[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   int i;
76  if (context) {
77     DEBUG1("smx_ctx_ruby_free_context(%p)",context);
78     /* free argv */
79     if (context->argv) {
80       for (i = 0; i < context->argc; i++)
81         if (context->argv[i])
82           free(context->argv[i]);
83
84       free(context->argv);
85     }
86     free (context);
87     context = NULL;
88   }
89 }
90
91 static void smx_ctx_ruby_start(smx_context_t context) {
92   DEBUG1("smx_ctx_ruby_start(%s) (nothing to do)",context->argv[0]);
93   /* Already Done .. Since a Ruby process is launched within initialization
94      We Start it Within the Initializer ... We Use the Semaphore To Keep
95      the thread alive waiting for mutex signal to execute the main*/
96 }
97
98 static void smx_ctx_ruby_stop(smx_context_t context) {
99   DEBUG0("smx_ctx_ruby_stop()");
100   VALUE process = Qnil;
101   smx_ctx_ruby_t ctx_ruby,current;
102
103   if ( context->cleanup_func)
104     (*(context->cleanup_func)) (context->cleanup_arg);
105
106   ctx_ruby = (smx_ctx_ruby_t) context;
107   
108   if ( simix_global->current_process->iwannadie ) {
109     if( ctx_ruby->process ) {
110       
111       //if the Ruby Process still Alive ,let's Schedule it
112       if ( rb_process_isAlive( ctx_ruby->process ) ) {
113
114         current = (smx_ctx_ruby_t)simix_global->current_process->context;       
115         rb_process_schedule(current->process);
116         process = ctx_ruby->process;
117         // interupt/kill The Ruby Process
118         rb_process_kill_up(process);
119       }
120     }
121   } else {
122
123     if (ctx_ruby->process) 
124      ctx_ruby->process = Qnil;
125
126   }
127 }
128
129 static void smx_ctx_ruby_suspend(smx_context_t context) {
130
131     DEBUG1("smx_ctx_ruby_suspend(%s)",context->argv[0]);
132     smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) context;
133     if (ctx_ruby->process)
134       rb_process_unschedule(ctx_ruby->process);
135 }
136
137 static void smx_ctx_ruby_resume(smx_context_t old_context,smx_context_t new_context) {
138   DEBUG2("smx_ctx_ruby_resume(%s,%s)",
139       (old_context->argc?old_context->argv[0]:"maestro"),
140       (new_context->argc?new_context->argv[0]:"maestro"));
141
142   smx_ctx_ruby_t ctx_ruby = (smx_ctx_ruby_t) new_context;
143   rb_process_schedule(ctx_ruby->process);
144
145 }