Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Integrate xbt_context_init/exit to the regular module mecanism; free the xbt_binary_n...
[simgrid.git] / src / xbt / context_win32.c
1 /********************************************************************************
2  * Copyright (c) 2003, 2004                                                     *
3  * Panagiotis E. Hadjidoukas    (peh@hpclab.ceid.upatras.gr)                    *
4  * HPCLab - University of Patras. All Rights Reserved.                          *
5  * Unix ucontext_t on Windows Operating System, May 2004 (revision 1)           *
6  *                                                                              *
7  * The author disclaims all warranties with regard to this software including   *
8  * all implied warranties of merchantability and fitness for a particular       *
9  * purpose. In no event shall HPCLab be liable for any special, indirect,       *
10  * or consequential damages or any damages whatsoever resulting from            *
11  * loss of use, data or profits, whether in action of contract negligence,      *
12  * or other tortious action, arising out of or in connection with the use       *
13  * or performance of this software.                                             *
14  ********************************************************************************/
15
16 /* The original author granted me (Martin Quinson) to redistribute this work 
17    under the LGPL licence, what I here do. */
18
19 #include "context_win32.h" /* Current file is to be included when cross-compiling, 
20                               but not during native builds. So this include is needed */
21
22 int getcontext(ucontext_t *ucp)
23 {
24         int ret;
25
26         /* Retrieve the full machine context */
27         ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;
28         ret = GetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);
29
30         return (ret == 0) ? -1: 0;
31 }
32
33 int setcontext(const ucontext_t *ucp)
34 {
35         int ret;
36         
37         /* Restore the full machine context (already set) */
38         ret = SetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);
39
40         return (ret == 0) ? -1: 0;
41 }
42
43 int makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
44 {
45         int i;
46     va_list ap;
47         char *sp;
48
49         /* Stack grows down */
50         sp = (char *) (size_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size;     
51
52         /* Reserve stack space for the arguments (maximum possible: argc*(8 bytes per argument)) */
53         sp -= argc*8;
54
55         if ( sp < (char *)ucp->uc_stack.ss_sp) {
56                 /* errno = ENOMEM;*/
57                 return -1;
58         }
59
60         /* Set the instruction and the stack pointer */
61         ucp->uc_mcontext.Eip = (unsigned long) func;
62         ucp->uc_mcontext.Esp = (unsigned long) sp - 4;
63
64         /* Save/Restore the full machine context */
65         ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;
66
67         /* Copy the arguments */
68         va_start (ap, argc);
69         for (i=0; i<argc; i++) {
70                 memcpy(sp, ap, 8);
71                 (char*)ap +=8;
72                 sp += 8;
73         }
74         va_end(ap);
75
76         return 0;
77 }
78
79 int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
80 {
81         int ret;
82
83         if ((oucp == NULL) || (ucp == NULL)) {
84                 /*errno = EINVAL;*/
85                 return -1;
86         }
87
88         ret = getcontext(oucp);
89         if (ret == 0) {
90                 ret = setcontext(ucp);
91         }
92         return ret;
93 }