#ifndef _threads_h
#define _threads_h

#ifndef NULL
#include <stdlib.h>
#endif

/* Include the platform dependant types */
#include <Types.h>
#include "memory.h"

#include "Threads.h"
#include "events.h"

/////////////////////////
// TYPEDEFS AND DEFINES//
/////////////////////////
#define PROCESSORS 1        /* This will change to something else. */
#define STACK_SIZE 16384    /* This is yet to be set to optimal value */
#define SAVE_SIZE 52        /* This is exact. */
#define PRIORITY_LEVELS 3   /* Each priority has a thread queue */

///////////////////////////
// MACROS TO SAVE TYPING //
///////////////////////////
#define TNPTR struct Thread_Node *
#define TN struct Thread_Node
#define PQH(x) Priority_Queue_Head[x]
#define PQT(x) Priority_Queue_Tail[x]

////////////////////
// DATASTRUCTURES //
////////////////////

/* FIXME: Add an enum for the offsets of the save area in bytes */

struct Thread_Node {
  Address save_area_base;       
  Byte required_cpu;           
  Handle ThreadID;              
  Handle ParentID;              
  struct Thread_Node *next;     
  struct Thread_Node *previous;
  UInt32 Handlers_Registered;
  Byte Priority;
  EventID Message_Arrived; /* The event thats generated when a
				   message arrives */
};

/* FIXME: This should go in the platform dependant code */
struct null_frame {

  int null_value;
  Address save_area;

};

//////////////////////
// GLOBAL VARIABLES //
//////////////////////

struct Thread_Node *Priority_Queue_Head[PRIORITY_LEVELS];
struct Thread_Node *Priority_Queue_Tail[PRIORITY_LEVELS];

/* Disposal Queue */
struct Thread_Node *Disposal_Queue;

////////////////////////////
// C FUNCTION DEFINATIONS //
////////////////////////////

void Invariant();
void Frame_Invariant();
void Thread_Closing();
void Destroy();
void ShutdownRuntime();
void Dump_Thread_Queue();

#endif



