2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
5 Desc: RunProcess() - Run a process from an entry point with args
9 #include <aros/asmcall.h> /* LONG_FUNC */
11 #include <dos/dosextens.h>
12 #include <proto/exec.h>
15 #include <aros/debug.h>
19 #include <boost/preprocessor/repetition/enum.hpp>
21 #define ARGS(z, n, text) text[n]
24 static void SwapTaskStackLimits(APTR
*lower
, APTR
*upper
)
26 struct Task
* this = FindTask(NULL
);
29 tmp
= this->tc_SPLower
;
30 this->tc_SPLower
= *lower
;
33 tmp
= this->tc_SPUpper
;
34 this->tc_SPUpper
= *upper
;
38 static void CallEntry(
41 struct StackSwapStruct
* sss
,
47 #error You need to write the AROS_UFC3R macro for your CPU
51 = AROS_UFC3R(ULONG
, entry
,
52 AROS_UFCA(STRPTR
, argptr
, A0
),
53 AROS_UFCA(ULONG
, argsize
, D0
),
54 AROS_UFCA(struct ExecBase
*, SysBase
, A6
),
56 (sss
->stk_Upper
- (ULONG
)sss
->stk_Lower
) /* used by m68k-linux arch, needed?? */
60 static void trampoline(void (*func
)(), IPTR args
[])
62 /* this was called from CallWithStack which also called Disable */
69 D(bug("swapped context: test = 0x%x\n", &test));
73 func(BOOST_PP_ENUM(MAXARGS
, ARGS
, args
));
75 /* this was called from CallWithStack which will enable again */
81 void (*func
)(), void* stack
, size_t size
, int argc
, IPTR args
[]
84 ucontext_t ucx
, ucx_return
;
86 Disable(); /* To avoid random crashes during startup */
87 if (argc
> MAXARGS
|| getcontext(&ucx
) == -1)
94 ucx
.uc_stack
.ss_sp
= stack
;
95 ucx
.uc_stack
.ss_size
= size
;
96 ucx
.uc_stack
.ss_flags
= SS_ONSTACK
;
98 ucx
.uc_link
= &ucx_return
;
100 APTR SPLower
= stack
, SPUpper
= stack
+ size
;
103 UBYTE
* startfill
= SPLower
;
104 const UBYTE
* endfill
= SPUpper
;
106 while (startfill
< endfill
)
113 makecontext(&ucx
, (void (*)()) trampoline
, 2, func
, args
);
116 we enable again in trampoline, after we have swapped
117 the new stack borders into the task structure
120 SwapTaskStackLimits(&SPLower
, &SPUpper
);
122 BOOL success
= swapcontext(&ucx_return
, &ucx
) != -1;
124 SwapTaskStackLimits(&SPLower
, &SPUpper
);
130 /**************************************************************************
133 LONG
AROS_SLIB_ENTRY(RunProcess
,Dos
) (
136 struct Process
* proc
,
137 struct StackSwapStruct
* sss
,
141 struct DosLibrary
* DOSBase
)
144 Sets the stack as specified and calls the routine with the given
148 proc - Process context
150 argptr - Pointer to argument string
151 argsize - Size of the argument string
152 entry - The entry point of the function
153 DOSBase - Pointer to dos.library structure
156 The return value of (*entry)();
168 **************************************************************************/
171 APTR oldReturnAddr
= proc
->pr_ReturnAddr
; /* might be changed by CallEntry */
175 (IPTR
) &proc
->pr_ReturnAddr
,
178 argsize
== -1 ? strlen(argptr
) : argsize
, /* Compute argsize automatically */
185 D(bug("before callwithstack; org context: test = 0x%x\n", &test));
189 /* Call the function with the new stack */
192 (void *) sss
->stk_Lower
,
193 (size_t) sss
->stk_Upper
- (size_t) sss
->stk_Lower
,
200 D(bug("after callwithstack; org context: test = 0x%x\n", &test));
204 proc
->pr_ReturnAddr
= oldReturnAddr
;