Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
correction to compile with warning and th indentation in my files
[simgrid.git] / src / simix / smx_context_sysv.c
1 /* context_sysv - context switching with ucontextes from System V           */
2
3 /* Copyright (c) 2009, 2010. 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
10
11 #include "smx_context_sysv_private.h"
12
13 #ifdef HAVE_VALGRIND_VALGRIND_H
14 #  include <valgrind/valgrind.h>
15 #endif /* HAVE_VALGRIND_VALGRIND_H */
16
17 #ifdef _XBT_WIN32
18         #include "ucontext.h"
19         #include "ucontext.c"
20 #endif
21
22 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
23
24 static smx_context_t 
25 smx_ctx_sysv_create_context(xbt_main_func_t code, int argc, char** argv,
26     void_f_pvoid_t cleanup_func, void* cleanup_arg);
27
28
29 static void smx_ctx_sysv_wrapper(void);
30
31 void SIMIX_ctx_sysv_factory_init(smx_context_factory_t *factory) {
32
33   smx_ctx_base_factory_init(factory);
34
35   (*factory)->create_context = smx_ctx_sysv_create_context;
36   /* Do not overload that method (*factory)->finalize */
37   (*factory)->free = smx_ctx_sysv_free;
38   (*factory)->stop = smx_ctx_sysv_stop;
39   (*factory)->suspend = smx_ctx_sysv_suspend;
40   (*factory)->resume = smx_ctx_sysv_resume;
41   (*factory)->name = "smx_sysv_context_factory";
42 }
43
44 smx_context_t
45 smx_ctx_sysv_create_context_sized(size_t size, xbt_main_func_t code, int argc, char** argv,
46     void_f_pvoid_t cleanup_func, void* cleanup_arg) {
47
48   smx_ctx_sysv_t context = (smx_ctx_sysv_t)smx_ctx_base_factory_create_context_sized
49       (size, code,argc,argv,cleanup_func,cleanup_arg);
50
51   /* If the user provided a function for the process then use it
52      otherwise is the context for maestro */
53   if(code){
54
55     xbt_assert2(getcontext(&(context->uc)) == 0,
56         "Error in context saving: %d (%s)", errno, strerror(errno));
57
58     context->uc.uc_link = NULL;
59
60     context->uc.uc_stack.ss_sp =
61         pth_skaddr_makecontext(context->stack, CONTEXT_STACK_SIZE);
62
63     context->uc.uc_stack.ss_size =
64         pth_sksize_makecontext(context->stack, CONTEXT_STACK_SIZE);
65
66 #ifdef HAVE_VALGRIND_VALGRIND_H
67     context->valgrind_stack_id =
68         VALGRIND_STACK_REGISTER(context->uc.uc_stack.ss_sp,
69             ((char *) context->uc.uc_stack.ss_sp) +
70             context->uc.uc_stack.ss_size);
71 #endif /* HAVE_VALGRIND_VALGRIND_H */
72
73     makecontext(&((smx_ctx_sysv_t)context)->uc, smx_ctx_sysv_wrapper, 0);
74   }
75
76   return (smx_context_t)context;
77
78 }
79
80 static smx_context_t
81 smx_ctx_sysv_create_context(xbt_main_func_t code, int argc, char** argv,
82     void_f_pvoid_t cleanup_func, void* cleanup_arg) {
83
84   return smx_ctx_sysv_create_context_sized(sizeof(s_smx_ctx_sysv_t),
85       code,argc,argv,cleanup_func,cleanup_arg);
86
87 }
88
89 void smx_ctx_sysv_free(smx_context_t context) {
90
91   if (context){
92
93 #ifdef HAVE_VALGRIND_VALGRIND_H
94     VALGRIND_STACK_DEREGISTER(((smx_ctx_sysv_t) context)->valgrind_stack_id);
95 #endif /* HAVE_VALGRIND_VALGRIND_H */
96
97   }
98   smx_ctx_base_free(context);
99 }
100
101 void smx_ctx_sysv_stop(smx_context_t context) {
102   smx_ctx_base_stop(context);
103
104   smx_ctx_sysv_suspend(context);
105 }
106
107 void smx_ctx_sysv_wrapper() {
108   /*FIXME: I would like to avoid accessing simix_global to get the current
109     context by passing it as an argument of the wrapper function. The problem
110     is that this function is called from smx_ctx_sysv_start, and uses
111     makecontext for calling it, and the stupid posix specification states that
112     all the arguments of the function should be int(32 bits), making it useless
113     in 64-bit architectures where pointers are 64 bit long.
114    */
115   smx_ctx_sysv_t context = 
116       (smx_ctx_sysv_t)simix_global->current_process->context;
117
118   (context->super.code) (context->super.argc, context->super.argv);
119
120   smx_ctx_sysv_stop((smx_context_t)context);
121 }
122
123 void smx_ctx_sysv_suspend(smx_context_t context) {
124   ucontext_t maestro_ctx = ((smx_ctx_sysv_t)simix_global->maestro_process->context)->uc;
125
126   int rv = swapcontext(&((smx_ctx_sysv_t) context)->uc, &maestro_ctx);
127
128   xbt_assert0((rv == 0), "Context swapping failure");
129 }
130
131 void smx_ctx_sysv_resume(smx_context_t new_context) {
132   smx_ctx_sysv_t maestro = (smx_ctx_sysv_t)simix_global->maestro_process->context;
133
134   int rv = swapcontext(&(maestro->uc), &((smx_ctx_sysv_t)new_context)->uc);
135
136   xbt_assert0((rv == 0), "Context swapping failure");
137 }