/*----------------------------------------------------------------------
   sched.h

   Copyright (c) 1992-1994 Raima Corporation.  All Rights Reserved.
----------------------------------------------------------------------*/

#ifndef SCHED_H
#define SCHED_H

/* Shared memory id's for unix global shared memory semaphores */
#define SCHED_SHM_ID_NCP     1  
#define SCHED_SHM_PERMISSION 0777
#define SCHED_SHM_TOK_FILE_LIT ".RDS.SCHED.MEM"
#define SCHED_SEM_TOK_FILE_LIT ".RDS.SCHED.SEM"

#if defined(UNIX) || defined(WATC)
#ifdef AIX
#pragma alloca
#endif
#define THREADSTACK (3000 * sizeof(int))
#else
#ifdef WATC
#define THREADSTACK (3000 * sizeof(int))
#else
#ifdef WIN32_NT
#define THREADSTACK (5000 * sizeof(int))
#else
#if defined(__IBMC__) || defined(__IBMCPP__)
#define THREADSTACK (5000 * sizeof(int))
#else
#define THREADSTACK (2000 * sizeof(int))
#endif
#endif
#endif
#endif

typedef struct {                /* Standard queue header */
    unsigned short maxNtry;     /* Max number of entries in queue */
    unsigned short numNtry;     /* Current number of entries */
    short waiting;              /* Indicates presence of waiting thread */
    short qFirst;               /* Index of first entry */
    short qLast;                /* Index of last entry */
    short qFree;                /* Index of first free item in queue */
    struct _RQUEUE *queue;      /* Pointer to queue itself */
    short qType;                /* Type of queue */
    short units;                /* # of units in this semaphore */
    short enaflg;               /* SET when semaphore is enabled */
                                /* The following fields are for the queued
                                   controlling LWT */
    short standaloneSem;        /* For standalone, threaded operation */
} QHEADER;

typedef struct _RQUEUE {    /*** The standard queue */
    short qNext;    /* [all] */
    short qStat;    /* [all] */
    unsigned short thID;    /* ID of thread at this entry [RUNQUEUE] */
    short stat;     /* Stat to re-start thread with [RUNQUEUE] */
    QHEADER *rdyQ;  /* Which ready Q he belongs in [SLEEPQUEUE] [SEMQUEUE] [BLKQUEUE] */
    long wake;      /* Take at which to wake this thread [SLEEPQUEUE] */
    QHEADER *lnkQ;  /* Associated queue, if any (NULL otherwise) [SLEEPQUEUE] */
    short lnkndx;   /* Position in associated queue, if any [SLEEPQUEUE] */
    short units;    /* # of units he wants from semaphore [SEMQUEUE] */
    short sndx;     /* Associate entry in sleepQ, if there is one [SEMQUEUE] [BLKQUEUE] */
                    /* QNULL otherwise */
    short pflag;    /* SET if this entry has been processed [SEMQUEUE] */
} RQUEUE;

extern QHEADER      *chkQSem;    /* checkpoint action quiescence semaphore */
extern QHEADER      *chgQSem;    /* transaction quiescence semaphore */
extern QHEADER      *newSchSem;  /* inserting new key */
extern QHEADER      *hNormSh;    /* Semaphore for Normal NCP Q */
extern QHEADER      *hPriSh;     /* Semaphore for Priority NCP Q */

/* Scheduler constants */
#define SCHP            0
#define SCNORM          1
#define SCBKGND         2
#define SERVER_SCHEDULER_THREAD 0 

/* Error constants */
#define T_OKAY          0
#define T_NOMEM         (-1)
#define T_NOTHD         (-2)
#define T_QFULL         (-3)
#define T_BFLAG         (-4)
#define T_QEMPTY        (-5)
#define T_BADNDX        (-6)
#define T_QNOTACT       (-7)
#define T_QERR          (-8)
#define T_BADPRI        (-9)
#define T_BADQTYPE      (-10)
#define T_BADSEM        (-11)
#define T_TIMEOUT       (-12)
#define T_BADUNITS      (-13)
#define T_BADBLK        (-14)
#define T_NOTBLOCKED    (-15)
#define T_NOTDISABLED   (-16)
#define T_INTERNALERR   (-17)
#define T_INUSE         (-18)

/* Information statuses */
#define T_EOQ           1

short REXTERNAL schBlock(
    short *, 
    short);

short REXTERNAL schInited(
    void );

short REXTERNAL schInit(
    unsigned short, 
    int, 
    short,
    short);

short REXTERNAL schCreateSem(
    QHEADER **,
    short,
    short);

short REXTERNAL schDeleteSem(
    QHEADER *);

short REXTERNAL schCreateThread(
    void (REXTERNAL *)(unsigned short),
    short, 
    unsigned short *);

short REXTERNAL schGO(
    void);

short REXTERNAL schRecvSem(
    QHEADER *,
    short, 
    short, 
    short);

short REXTERNAL schSendSem(
    QHEADER *,
    short,
    short);

short REXTERNAL schSleep(
    short);

short REXTERNAL schIsBlocked(
    short);

short REXTERNAL schUnBlock(
    short,
    short);

void  REXTERNAL schYield(
    void);

void REXTERNAL semStart(
    void);

void REXTERNAL semClear(
    void);

void REXTERNAL semWait(
    void);

void RINTERNAL schFatalExit(
    char *msg,
    short errNum);

short REXTERNAL schDisSem(
    QHEADER *hqsemQ,
    short flags);

short REXTERNAL schEnaSem(
    QHEADER *hqsemQ,
    short flags);

short REXTERNAL schWaitSem(
    QHEADER *hqsemQ,
    short time,
    short flags);

void REXTERNAL schThreadZero(
    short mode );

short REXTERNAL thFrameSize(
    unsigned short n,
    int size);

short RINTERNAL thNew(
    void (REXTERNAL *fcn)(unsigned short),
    unsigned short *pNewTHreadID);

short REXTERNAL bgrQueue(
    short,
    QHEADER *,
    short);

/* scheduler actions which can be requested by a background thread */
#define SCH_UNBLOCK     1
#define SCH_ENASEM      2
#define SCH_SENDSEM     3

/* Queue types */
#define HPRDYQ          1
#define NORMRDYQ        2
#define BKGNDRDYQ       3
/* *** IMPORTANT: HPRDYQ, NORMRDYQ and BKGNDRDYQ MUST be 1,2,3 respectively.
    and there must be nothing defined for 0 */

#define SLPQ            4
#define SEMQ            5
#define MSGQ            6
#define BLKQ            7
#define QSEMQ           8

/* Semaphore flags */
#define SEM_NORMAL      0x01
#define SEM_QUIESC      0x02
#define SEM_ALLOCED     0x04

/* Flag (bit field) definitions */
#define FYIELD          0x1

void REXTERNAL thJump(
    unsigned short);        /* Jump to another thread */

void REXTVARARG thReport(
    short level,
    char *msg,
    ...
);
#endif /* SCHED_H */

/*
$Header:   P:/PAT/INCLUDE/VCS/SCHED.H_V   1.39   10 Jan 1995 15:43:30   WAYNE  $
*/
