Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
3051d05d6a76f61a8cb09613b74e8bed0576976b
[simgrid.git] / src / xbt / win32_ucontext.c
1 /*\r
2  *      win32-ucontext: Unix ucontext_t operations on Windows platforms\r
3  *      Copyright(C) 2007 Panagiotis E. Hadjidoukas\r
4  *\r
5  *      Contact Email: phadjido@cs.uoi.gr, xdoukas@ceid.upatras.gr\r
6  *\r
7  *      win32-ucontext is free software; you can redistribute it and/or\r
8  *      modify it under the terms of the GNU Lesser General Public\r
9  *      License as published by the Free Software Foundation; either\r
10  *      version 2 of the License, or (at your option) any later version.\r
11  *\r
12  *      win32-ucontext is distributed in the hope that it will be useful,\r
13  *      but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
15  *      Lesser General Public License for more details.\r
16  *\r
17  *      You should have received a copy of the GNU Lesser General Public\r
18  *      License along with QueueUserAPCEx in the file COPYING.LIB;\r
19  *      if not, write to the Free Software Foundation, Inc.,\r
20  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\r
21  */\r
22 \r
23 #include "ucontext.h"\r
24 \r
25 int getcontext(ucontext_t *ucp)\r
26 {\r
27         int ret;\r
28 \r
29         /* Retrieve the full machine context */\r
30         ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;\r
31         ret = GetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);\r
32 \r
33         return (ret == 0) ? -1: 0;\r
34 }\r
35 \r
36 int setcontext(const ucontext_t *ucp)\r
37 {\r
38         int ret;\r
39 \r
40         /* Restore the full machine context (already set) */\r
41         ret = SetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);\r
42 \r
43         return (ret == 0) ? -1: 0;\r
44 }\r
45 \r
46 int makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)\r
47 {\r
48         int i;\r
49     va_list ap;\r
50         char *sp;\r
51 \r
52         /* Stack grows down */\r
53         sp = (char *) (size_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size;\r
54 \r
55         /* Reserve stack space for the arguments (maximum possible: argc*(8 bytes per argument)) */\r
56         sp -= argc*8;\r
57 \r
58         if ( sp < (char *)ucp->uc_stack.ss_sp) {\r
59                 /* errno = ENOMEM;*/\r
60                 return -1;\r
61         }\r
62 \r
63         /* Set the instruction and the stack pointer */\r
64         ucp->uc_mcontext.Eip = (unsigned long) func;\r
65         ucp->uc_mcontext.Esp = (unsigned long) sp - 4;\r
66 \r
67         /* Save/Restore the full machine context */\r
68         ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;\r
69 \r
70         /* Copy the arguments */\r
71         va_start (ap, argc);\r
72         for (i=0; i<argc; i++) {\r
73                 memcpy(sp, ap, 8);\r
74                 ap +=8;\r
75                 sp += 8;\r
76         }\r
77         va_end(ap);\r
78 \r
79         return 0;\r
80 }\r
81 \r
82 int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)\r
83 {\r
84         int ret;\r
85 \r
86         if ((oucp == NULL) || (ucp == NULL)) {\r
87                 /*errno = EINVAL;*/\r
88                 return -1;\r
89         }\r
90 \r
91         ret = getcontext(oucp);\r
92         if (ret == 0) {\r
93                 ret = setcontext(ucp);\r
94         }\r
95         return ret;\r
96 }\r