Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mv include/xbt/context.h src/include/xbt/context.h since users shouldn't mess with it
[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" Not needed since this file is to be included*/
20
21 int getcontext(ucontext_t *ucp)
22 {
23         int ret;
24
25         /* Retrieve the full machine context */
26         ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;
27         ret = GetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);
28
29         return (ret == 0) ? -1: 0;
30 }
31
32 int setcontext(const ucontext_t *ucp)
33 {
34         int ret;
35         
36         /* Restore the full machine context (already set) */
37         ret = SetThreadContext(GetCurrentThread(), &ucp->uc_mcontext);
38
39         return (ret == 0) ? -1: 0;
40 }
41
42 int makecontext(ucontext_t *ucp, void (*func)(), int argc, ...)
43 {
44         int i;
45     va_list ap;
46         char *sp;
47
48         /* Stack grows down */
49         sp = (char *) (size_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size;     
50
51         /* Reserve stack space for the arguments (maximum possible: argc*(8 bytes per argument)) */
52         sp -= argc*8;
53
54         if ( sp < (char *)ucp->uc_stack.ss_sp) {
55                 /* errno = ENOMEM;*/
56                 return -1;
57         }
58
59         /* Set the instruction and the stack pointer */
60         ucp->uc_mcontext.Eip = (unsigned long) func;
61         ucp->uc_mcontext.Esp = (unsigned long) sp - 4;
62
63         /* Save/Restore the full machine context */
64         ucp->uc_mcontext.ContextFlags = CONTEXT_FULL;
65
66         /* Copy the arguments */
67         va_start (ap, argc);
68         for (i=0; i<argc; i++) {
69                 memcpy(sp, ap, 8);
70                 ap +=8;
71                 sp += 8;
72         }
73         va_end(ap);
74
75         return 0;
76 }
77
78 int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
79 {
80         int ret;
81
82         if ((oucp == NULL) || (ucp == NULL)) {
83                 /*errno = EINVAL;*/
84                 return -1;
85         }
86
87         ret = getcontext(oucp);
88         if (ret == 0) {
89                 ret = setcontext(ucp);
90         }
91         return ret;
92 }