/* 
 * process.h
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * $Revision: 1.2 $
 * $Date: 1996/02/01 15:24:25 $
 * 
 * HISTORY
 * $Log: process.h,v $
 * Revision 1.2  1996/02/01 15:24:25  slm
 * Updated copyright and version.
 *
 * Revision 1.1  1995/07/28  22:49:20  slm
 * Initial revision
 *
 * Revision 1.3  1994/12/02  18:46:06  hkaram
 * Added declarations
 *
 * Revision 1.2  1994/11/22  21:25:37  hkaram
 * Changed Pfi to Ptrfi
 *
 * Revision 1.1  1994/10/26  20:36:21  hkaram
 * Initial revision
 */

#ifndef process_h
#define process_h

#include "xtype.h"

#include "pthread.h"

/* the "normal" priority for process creation */
#define STD_PRIO       10
#define THREAD_MAXPRIO 20
#define THREAD_MINPRIO (-20)

#ifndef NULL
#define NULL 0
#endif


#if (defined(USE_GC) && !defined(sparc))        /* not for sparc */
#define malloc(X) gc_malloc(X)
#define free(X) gc_free(X)
#endif

#if 0
typedef struct {
#ifdef sun
  int pc, smask, onstack;
  int d2, d3, d4, d5, d6, d7;
  int a2, a3, a4, a5, a6;
  long *sp;
#endif
#ifdef vax
  long *pc, *sp, *fp, *ap;
  int r6, r7, r8, r9, r10, r11;
#endif
} jmp_buf;
#endif

typedef struct _Process {
#if 0
  jmp_buf		jb;
#endif
  long 			*stack, *stacklimit;
  short			prio;
  struct _Process *	link;
  int			extrastuff;
  int			index;
#ifdef MUTS
  void *muts;
#endif
#ifdef sparc
  pthread_t             thread;	/* cjt */
#endif
} Process;
#define STACKSIZE (32*1024)


typedef struct sSemaphore {
#ifdef sparc	/* -- Robbert van Renesse:  a condition variable for sync */
  pthread_cond_t		 cv;
#else
  struct _Process		*head;
  struct _Process	       **tail;
#endif
  short				 unused;
  short				 count;
} Semaphore;


extern pthread_mutex_t	master_monitor;
#define xk_master_lock() 	pthread_mutex_lock( & master_monitor )
#define xk_master_unlock()	pthread_mutex_unlock( &master_monitor )

typedef int (*Ptrfi)();

#ifdef __STDC__

extern semInit( Semaphore *, unsigned );
extern void semWait( Semaphore *);
extern void semSignal( Semaphore *);
extern realP( Semaphore * );
extern realV( Semaphore * );


int	CreateProcess0( Ptrfi, short );
int	CreateProcess1( Ptrfi, short, int );
int	CreateProcess2( Ptrfi, short, int, int );
int	CreateProcess3( Ptrfi, short, int, int, int );
int	CreateProcess4( Ptrfi, short, int, int, int, int );
int	CreateProcess5( Ptrfi, short, int, int, int, int, int );
int	CreateProcess6( Ptrfi, short, int, int, int, int, int, int );

#else

extern semInit( );
extern void semWait( );
extern void semSignal( );
extern realP( );
extern realV( );


int	CreateProcess0( );
int	CreateProcess1( );
int	CreateProcess2( );
int	CreateProcess3( );
int	CreateProcess4( );
int	CreateProcess5( );
int	CreateProcess6( );

#endif __STDC__



extern Process *Active;
extern int	SignalsPossible;
#define kSwitch() Yield()

#define Q_INIT(Q) { \
  (Q)->head = NULL; \
  (Q)->tail = &(Q)->head; \
}

#define Q_EMPTY(Q) ((Q)->tail == &(Q)->head)

#define Q_INSERTLAST(Q, E) { \
  *((Q)->tail) = (E); \
  (E)->link = NULL; \
  (Q)->tail = &(E)->link; \
}

#define Q_INSERTFIRST(Q, E) { \
  (E)->link = (Q)->head; \
  (Q)->head = (E); \
  if (Q_EMPTY(Q)) (Q)->tail = &(E)->link; \
}

#define Q_REMOVEFIRST(Q, E) { \
  if ((E) = (Q)->head) { \
    if (! ((Q)->head = (E)->link)) (Q)->tail = &(Q)->head; \
  } \
}

#endif
