Aros/Developer/Docs/Examples/StackSwap
Appearance
The AmigaOS StackSwap function isn't designed to be reliably used from C code. This is why AmigaOS 4 has the NewStackRun function f.e.
Here's a solution that uses CreateNewProc:
#include <exec/exec.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdio.h>
/* 5 MB stack */
#define REQUIRED_STACK_SIZE (5L << 20)
struct StartMessage {
struct Message msg;
int argc;
char **argv;
int rc;
};
void proc_entry ();
int real_main (int argc, char *argv[]);
int main (int argc, char *argv[]) {
struct Process *myproc = (struct Process *)FindTask(NULL);
IPTR stacksize = (IPTR)myproc->pr_Task.tc_SPUpper - (IPTR)myproc->pr_Task.tc_SPLower;
int rc;
printf("stack size: %dn", (int)stacksize);
if (stacksize >= REQUIRED_STACK_SIZE) {
printf("no stack adjustment was needed.n");
rc = real_main(argc, argv);
} else {
struct StartMessage msg;
struct Process *child_proc;
struct MsgPort *my_mp;
struct MsgPort *child_mp;
struct StartMessage *my_msg;
printf("stack was too small. creating a child process with required stack amount.n");
child_proc = CreateNewProcTags(
NP_Entry, proc_entry,
NP_StackSize, REQUIRED_STACK_SIZE,
TAG_END);
if (!child_proc) {
printf("failed to create child procn");
return RETURN_FAIL;
}
my_mp = &myproc->pr_MsgPort;
child_mp = &child_proc->pr_MsgPort;
msg.msg.mn_Node.ln_Type = NT_MESSAGE;
msg.msg.mn_Length = sizeof(msg);
msg.msg.mn_ReplyPort = my_mp;
msg.argc = argc;
msg.argv = argv;
PutMsg(child_mp, &msg.msg);
while (!(my_msg = (struct StartMessage *)GetMsg(my_mp))) {
WaitPort(my_mp);
}
rc = my_msg->rc;
}
return rc;
}
void proc_entry () {
struct Process *myproc = (struct Process *)FindTask(NULL);
IPTR stacksize = (IPTR)myproc->pr_Task.tc_SPUpper - (IPTR)myproc->pr_Task.tc_SPLower;
struct MsgPort *my_mp = &myproc->pr_MsgPort;
struct StartMessage *my_msg;
while (!(my_msg = (struct StartMessage *)GetMsg(my_mp))) {
WaitPort(my_mp);
}
printf("stack size: %dn", (int)stacksize);
my_msg->rc = real_main(my_msg->argc, my_msg->argv);
Forbid();
ReplyMsg(&my_msg->msg);
}
int real_main (int argc, char *argv[]) {
printf("Hello AROS World!n");
return RETURN_OK;
}