Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
70a41babaf6f77e8bb5793c29e4db3c4081094e5
[simgrid.git] / src / simix / smx_context.c
1 /* a fast and simple context switching library                              */
2
3 /* Copyright (c) 2004-2008 the SimGrid team.                                */
4 /* All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include "portable.h"
10 #include "xbt/log.h"
11 #include "xbt/swag.h"
12 #include "private.h"
13 #include <lua5.1/lauxlib.h>
14
15
16 #ifdef HAVE_RUBY
17 /* Damn Ruby. They load their full config.h, which breaks since we also load ours.
18  * So, we undef the offending defines
19  */
20 #undef PACKAGE_VERSION
21 #undef PACKAGE_NAME
22 #undef PACKAGE_TARNAME
23 #undef PACKAGE_STRING
24 #undef PACKAGE_BUGREPORT
25 #undef _GNU_SOURCE
26 #include <ruby.h>
27  void SIMIX_ctx_ruby_factory_init(smx_context_factory_t *factory);
28 #include "smx_context_ruby.c"
29 #endif 
30  
31 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_context, simix, "Context switching mecanism");
32
33 const char *xbt_ctx_factory_to_use = NULL;
34
35 /** 
36  * This function is call by SIMIX_global_init() to initialize the context module.
37  */
38
39 void SIMIX_context_mod_init(void)
40 {
41   if (!simix_global->context_factory) {
42   /* select context factory to use to create the context(depends of the macro definitions) */
43     if (xbt_ctx_factory_to_use) {
44       SIMIX_context_select_factory(xbt_ctx_factory_to_use);
45     } else {
46 #ifdef CONTEXT_THREADS
47     /* context switch based os thread */
48     SIMIX_ctx_thread_factory_init(&simix_global->context_factory);
49 #elif !defined(WIN32)
50     /* context switch based ucontext */
51     SIMIX_ctx_sysv_factory_init(&simix_global->context_factory);
52 #else
53     /* context switch is not allowed on Windows */
54 #error ERROR [__FILE__, line __LINE__]: no context based implementation specified.
55 #endif
56     }
57   }
58 }
59
60 /**
61  * This function is call by SIMIX_clean() to finalize the context module.
62  */
63 void SIMIX_context_mod_exit(void)
64 {
65   if (simix_global->context_factory) {
66     smx_pfn_context_factory_finalize_t finalize_factory;
67     
68     /* finalize the context factory */
69     finalize_factory = simix_global->context_factory->finalize;
70     (*finalize_factory) (&simix_global->context_factory);
71   }
72 }
73
74 /**
75  * This function is used to change the context factory.
76  * Warning: it destroy all the existing processes (even for maestro), and it
77  * will create a new maestro process using the new context factory.
78  */
79 int SIMIX_context_select_factory(const char *name)
80 {
81   /* if a context factory is already instantiated and it is different from the
82      newly selected one, then kill all the processes, exit the context module
83      and initialize the new factory.
84   */
85   
86
87   if (simix_global->context_factory != NULL) {
88     if (strcmp(simix_global->context_factory->name, name)){
89
90       SIMIX_process_killall();
91       
92       /* kill maestro process */
93       SIMIX_context_free(simix_global->maestro_process->context);
94       free(simix_global->maestro_process);  
95       simix_global->maestro_process = NULL;
96
97       SIMIX_context_mod_exit();
98     }
99     else
100       /* the same context factory is requested return directly */
101       return 0;
102   }
103   
104   /* init the desired factory */
105   SIMIX_context_init_factory_by_name(&simix_global->context_factory, name);
106
107   SIMIX_create_maestro_process ();
108
109
110   
111   return 0;
112 }
113
114 /**
115  * Initializes a context factory given by its name
116  */
117 void SIMIX_context_init_factory_by_name(smx_context_factory_t * factory,
118                                         const char *name)
119 {
120   
121   if (!strcmp(name, "java"))
122 #ifdef HAVE_JAVA     
123     SIMIX_ctx_java_factory_init(factory);
124 #else
125     THROW0(not_found_error, 0, "Factory 'Java' does not exist: Java support was not compiled in the SimGrid library");
126 #endif /* HAVE_JAVA */
127    
128   else if (!strcmp(name, "thread"))
129 #ifdef CONTEXT_THREADS
130     SIMIX_ctx_thread_factory_init(factory);
131 #else
132     THROW0(not_found_error, 0, "Factory 'thread' does not exist: thread support was not compiled in the SimGrid library");
133 #endif /* CONTEXT_THREADS */
134    
135     else if (!strcmp(name, "sysv"))
136   #if !defined(WIN32) && !defined(CONTEXT_THREADS)
137       SIMIX_ctx_sysv_factory_init(factory);
138   #else
139       THROW0(not_found_error, 0, "Factory 'sysv' does not exist: no System V thread support under Windows");
140   #endif
141     else if (!strcmp(name, "lua"))
142 #ifdef HAVE_LUA
143       SIMIX_ctx_lua_factory_init(factory);
144 #else
145
146     THROW0(not_found_error, 0, "Factory 'lua' does not exist: Lua support was not compiled in the SimGrid library");
147 #endif /* HAVE_LUA */
148
149     else if (!strcmp(name,"ruby"))
150 #ifdef HAVE_RUBY
151     SIMIX_ctx_ruby_factory_init(factory);
152 #else
153      THROW0(not_found_error, 0, "Factory 'ruby' does not exist: Ruby support was not compiled in the SimGrid library");
154 #endif
155   else
156     THROW1(not_found_error, 0, "Factory '%s' does not exist", name);
157 }