/*
    tm-include.h, Copyright  (c) by Christian Conrad,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public Licence.
 
    A full copy of the GNU GPL is provided in the file COPYING found in the 
    development root of Topsy.
*/
/*
	
	File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Threads/tm-include.h,v $
 	Author(s):             Christian Conrad
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 3041 $
 	Creation Date:         
 	Last Date of Change:   $Date: 2007-06-19 22:29:34 +0200 (Die, 19 Jun 2007) $      by: $Author: sryffel $
	
*/

#ifndef __TMINCLUDE_H
#define __TMINCLUDE_H

#include "Threads.h"
#include "HashList.h"
#include "List.h"
#include "Topsy.h"
#include "Messages.h"
#include "Configuration.h"
#include "tailq.h"
#include "Lock.h"


/* Internal TM error messages */
#define TM_OK                       1
#define TM_MSGQUEUEOVERFLOW        -1
#define TM_THREADNOTFOUND          -2
#define TM_THREADSTARTFAILED        0     /* as threadStart() returns an id (!= 0) */
#define TM_THREADKILLFAILED        -3
#define TM_NOSUCHMESSAGE           -4
#define TM_FAILED                  -5
#define TM_IPCFAILED							 -6
#define TM_THREADBUILDFAILED				0
#define TM_THREADBUILDOK						1

/* Priorities */
#define KERNEL_PRIORITY_HIGH				0			// highest priority
#define USER_PRIORITY_HIGH					10		// highest priority for user threads
#define IDLE_PRIORITY								NBPRIORITYLEVELS - 1	// lowest priority

/* Flags */
#define TM_INIT                     1     // during Init-Process, Kernel Threads not yet running
#define TM_NOFLAGS                  0     // nothing special
#define TM_KERNEL                   2     // argument is a kernel thread or a kernel mode entity

/* Forward definitions - these are necessary to prevent cyclical references */
typedef struct Thread_t* ThreadPtr;
typedef struct ProcContext_t* ProcContextPtr;  /* proc. dependent context */

/* Thread status in scheduler */
typedef enum {
  RUNNING,
  READY,
  BLOCKED
} SchedStatus;

/* Thread priority level (must match NBPRIORITYLEVELS)
	 Decreasing order of priority */
typedef uint8 ThreadPriority;

/* Permissions is now a bit field wich enables us to give various combi-   *
 * nations of permissions. We do not use the sign of the ID to distinguish *
 * between kernel and user anymore                                         */
/* Bit  0: is kernel-thread, ... more flags to come XXX                    */
typedef uint16 ThreadPermission;
#define KERNEL_PERM_MSK						1		/* Bit mask for kernel / user */

/* Two queues for each priority level */
typedef struct SchedPriority_t
{
  List ready;
  List blocked;
}
SchedPriority;

typedef struct Scheduler_t
{
  ThreadPtr running;
  SchedPriority prioList[NBPRIORITYLEVELS];
}
Scheduler;

typedef enum {
  NOT_WAITING,
  WAITING,
  FILLED
} PendingStatus;

/* Message queue for each thread */
typedef struct MessageQueue_t
{
  int freeList;                      /* index of first free cell */
  int busyList;                      /* index of first valid message */
  int ctrl[MAXNBMSGINQUEUE];         /* management of message list */
  Message msg[MAXNBMSGINQUEUE];      /* static array of messages */
  PendingStatus msgPendingStatus;    /* indicates if a message is pending */
  Message* msgPendingPtr;            /* reference on pending message */
  ThreadId threadIdPending;          /* expected message sender */
  MessageId msgIdPending;            /* expected message type */
}
MessageQueue;

/* Statistics about threads that may be gathered */
typedef struct ThreadStatistics_t
{
  int cpuCycles;
}
ThreadStatistics;

/* Scheduler specific data in each Thread structure */
typedef struct SchedulerInfo_t
{
  SchedStatus status;					/* BLOCKED, READY, RUNNING */
  ThreadPriority priority;		/* Priority of the thread */
  Address hint;								/* Backwards reference on list descriptor */
}
SchedulerInfo;

/* predefine pdom_t */
//typedef struct protection_domain *pdom_t;

/* Main thread structure */
typedef struct Thread_t
{
  ProcContextPtr contextPtr;		/* Processor dependent context */
  ThreadId id;									/* Processor independent */
  struct protection_domain *pdPtr;	/* Pointer to Protection domain */
  TAILQ_ENTRY(Thread_t) pdCont;		/* List of all Threads within the PD */
  char name[MAXNAMESIZE];				/* Logical name of the thread */
  ThreadId parentId;						/* Thread id of parent thread */
  Address stackStart;						/* Start of stack */
  Address stackEnd;							/* End of stack */
  MessageQueue msgQueue;				/* Message queue */
  SchedulerInfo schedInfo;			/* Scheduler specific data */
  ThreadPermission permission;	/* bitfield for various permissions */
  ThreadStatistics stat;				/* Various statistics */
  LockDesc lock;                /* Lock to protect schedInfo and the msgQueue */
}
Thread;


#endif
