#ifndef _THREAD 
#define _THREAD 
 
#include <setjmp.h> 
#include <stdio.h>

#include "queue.h"
#include "types.h" 
#include "standard.h"
 
typedef struct _Condition 
{ 
  PQueue  pBlockedQueue;  /* All the threads blocked on a condition */ 
  PQueue  pSignalsQueue;  /* All the signals pending to be delivered */ 
} *Condition, *PCondition; 
 
#define THREAD_STACK   16384
#define LOCALS_BUFFER  100
#define TIME_SLICE     100 
   
/* Machine dependant definitions of the stack pointer */ 
#ifdef DOS_GCC 
#define STACK_POINTER 3 
#elif  SUN_GCC 
#define STACK_POINTER 2
#elif  LINUX_GCC
#define STACK_POINTER 4 
#elif  DEC_GCC
#define STACK_POINTER 32
#endif
 
/* States (for internal usage) */ 
#define THREAD_WAITING 0 
#define THREAD_RUNNING 1 
#define THREAD_BLOCKED 2 
#define THREAD_NOTLIVE 3 
 
typedef struct _Thread 
{ 
  jmp_buf      State;          /* The context of the thread */
  Byte        *pStack;         /* The block of memory used as stack */
  ThreadFunc   thdProc;        /* The thread's startup function */
  any_ptr      pvArg;          /* An argument that gets passed to the thread */
  Int          iState;         /* The state of the thread (see above) */
  Priority     priPriority;    /* The priority of the thread */
  String       strThreadName;  /* The name of the thread */
} Thread; 

/* Thread functions */
int     t_start(ThreadFunc thdProc, any_ptr pvValue); 
void    t_fork(ThreadFunc thdProc, any_ptr pvValue); 
any_ptr t_wait(PCondition pCond); 
void    t_sig(PCondition pCond, any_ptr pvValue, 
	      Boolean fQueueSignal); 
void    t_yield(void); 
void    t_cs_entry(void); 
void    t_cs_exit(void); 

/* Real-time thread functions */
int    t_startRT(ThreadFunc thdProc, any_ptr pvValue, 
		    String strName, Priority priority, 
		            Boolean fCheckFail);
void   t_forkRT(ThreadFunc thdProc, any_ptr pvValue, 
			   String strName, Priority priority);
String t_name(void);
void   t_debug(FILE *hFile);
void   t_sig_urgent(PCondition pCond, any_ptr pvValue, 
			       Boolean fQueueSignal);
void   t_exit_all(int iValue);

/* Condition related functions */
Condition  cond_create(void); 
Boolean    cond_is_empty(PCondition pCond); 
void       cond_destroy(PCondition pCond); 
void       cond_registerRT(Condition pCond, clock_t clockInterval);
void       cond_unregisterRT(Condition pCond);
 
#endif 
