Logo AND Algorithmique Numérique Distribuée

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