#include <stdlib.h>
#include <stdio.h>
#include "cthread.hpp"
/* This module is compiler-specific. It relies on the
structure of jmp_buf and the C function prolog and
epilog to work properly */
/* The following definitions are for the Zortech V3.0
C++Windows and OS/2 compilers */
#define WORDSTOREMOVE 3 //used for stack adjustment
typedef struct //jmp_buf map
{
long ip; //CS:IP
short filler1;
long sp; //SS:SP
} *mapptr;
/* Used to transfer to the specified thread. The context
of the running thread is saved in the thread object's
private data area */
void Cthread::Transfer(Cthread &thread)
{
/* don't transfer control if the new thread's
stack is corrupt */
if ((thread.threadbody == NULL) ||
(thread.threadbody->Overflowed)) return;
/* save old thread's context and transfer control */
if (!setjmp(this->threadbody->Context))
longjmp(thread.threadbody->Context, 1);
}
/* Used to create a thread object and copy a number of
parameters to the thread's stack */
Cthread::Cthread(THDFN func, int stacksize,
int *frame, int framesize)
{
int i;
mapptr ptr;
/* allocate stack */
stacksize /= sizeof(int); //convert to out allocation unit
stacksize = (stacksize > THD_MAX_STACK) ? THD_MAX_STACK: stacksize;
threadbody = (THDPTR) new char[i = (sizeof(THD) - sizeof(int) *
(THD_MAX_STACK - stacksize))];
threadbody->Overflowed = 0;
threadbody->TotalLen = i;
if (threadbody == NULL)
{
printf("Thread creation failed...\n");
}
setjmp(threadbody->Context); //initialize jmp_buf structure
ptr = (mapptr) &threadbody->Context;
/* initialize stack with parameters if any */
if (stacksize)
{
if ((frame != NULL) && (stacksize > framesize))
{
for (i = 0; i < framesize; i++)
threadbody->Stack[stacksize - framesize + i] =
*frame++;
stacksize -= framesize;
}
//set stack pointer
ptr ->sp = (long) &(threadbody->Stack[stacksize -
WORDSTOREMOVE]);
}
/* set up the start of the thread body */
ptr->ip = (long) func;
}
/* Destructor */
Cthread::~Cthread(void)
{
delete [threadbody->TotalLen] (char *) threadbody;
threadbody = NULL;
}
// End of File