/*	@(#)sem.h	13.1 (RC International) 91/02/02	*/

#ifndef _SEM_H
#define _SEM_H

/*
**	IPC Semaphore Facility.
*/

/*
**	Implementation Constants.
*/

#define	PSEMN	(PZERO + 3)	/* sleep priority waiting for greater value */
#define	PSEMZ	(PZERO + 2)	/* sleep priority waiting for zero */

/*
**	Permission Definitions.
*/

#define	SEM_A	0200	/* alter permission */
#define	SEM_R	0400	/* read permission */

/*
**	Semaphore Operation Flags.
*/

#define	SEM_UNDO	010000	/* set up adjust on exit entry */

/*
**	Semctl Command Definitions.
*/

#define	GETNCNT	3	/* get semncnt */
#define	GETPID	4	/* get sempid */
#define	GETVAL	5	/* get semval */
#define	GETALL	6	/* get all semval's */
#define	GETZCNT	7	/* get semzcnt */
#define	SETVAL	8	/* set semval */
#define	SETALL	9	/* set all semval's */

/*
**	Structure Definitions.
*/

/*
**	There is one semaphore id data structure for each set of semaphores
**		in the system.
*/

struct semid_ds {
	struct ipc_perm	sem_perm;	/* operation permission struct */
	struct sem	*sem_base;	/* ptr to first semaphore in set */
	u_short		sem_nsems;	/* # of semaphores in set */
	time_t		sem_otime;	/* last semop time */
	time_t		sem_ctime;	/* last change time */
};

/*
**	There is one semaphore structure for each semaphore in the system.
*/

struct sem {
	u_short	semval;		/* semaphore text map address */
	pid_t	sempid;		/* pid of last operation */
	u_short	semncnt;	/* # awaiting semval > cval */
	u_short	semzcnt;	/* # awaiting semval = 0 */
};

/*
**	There is one sem_undo structure for each process requesting
**	an SEM_UNDO in the system.
**	These is one undo structure in the sem_undo structure for
**	each semaphore that a process requests an SEM_UNDO for.
*/

struct sem_undo {
	struct sem_undo	*un_np;	/* ptr to next active undo structure */
	short		un_cnt;	/* # of active entries */
	struct undo {
		short	un_aoe;	/* adjust on exit values */
		short	un_num;	/* semaphore # */
		int	un_id;	/* semid */
	}	un_ent[1];	/* undo entries (one minimum) */
};

/*
** semaphore information structure
*/
struct	seminfo	{
	int	semmap,		/* # of entries in semaphore map */
		semmni,		/* # of semaphore identifiers */
		semmns,		/* # of semaphores in system */
		semmnu,		/* # of sem_undo structures in system */
		semmsl,		/* max # of semaphores per id */
		semopm,		/* max # of operations per semop call */
		semume,		/* max # of undo entries per process */
		semusz,		/* size in bytes of sem_undo structure */
		semvmx,		/* semaphore maximum value */
		semaem;		/* adjust on exit max value */
};

/*
**	User semaphore template for semop system calls.
*/

struct sembuf {
	u_short	sem_num;	/* semaphore # */
	short	sem_op;		/* semaphore operation */
	short	sem_flg;	/* operation flags */
};

/*
 * The following manifest constants define the parameters
 * for the ipc semaphore facility.
 */

/*#define	SEMMAP	10	/* # of entries in semaphore map */
#define	SEMMAP	300	/* # of entries in semaphore map */
/*#define	SEMMNI	10	/* # of semaphore identifiers */
#define	SEMMNI	300	/* # of semaphore identifiers */
/*#define	SEMMNS	60	/* # of semaphores in system */
#define	SEMMNS	1024	/* # of semaphores in system */
#define	SEMMNU	30	/* # of undo structures in system */
/*#define	SEMMSL	25	/* max # of semaphores per id */
#define	SEMMSL	1024	/* max # of semaphores per id */
#define SEMOPM	10	/* max # of operations per semop call */
#define	SEMUME	10	/* max # of undo entries per process */
#define	SEMUSZ	((sizeof(struct sem_undo) - sizeof(struct undo))\
					    + sizeof(struct undo) * SEMUME)
#define	SEMVMX	32767	/* semaphore maximum value */
#define	SEMAEM	16384	/* adjust on exit max value */

union semtmp {
	short		semvals[SEMMSL];/* set semaphore values */
	struct semid_ds	ds;		/* set permission values */
	struct sembuf	semops[SEMOPM];	/* operation holding area */
};



/*
 * Structure and defines for usemop() system call
 */

struct	usem {
	u_int	owner:16;	/* owner of the lock */
	u_int	resev:15;	/* reserved for future use */
	u_int	locked:1;	/* the lock */
};

enum us_opercode
{
	US_CHECK	= 0,	/* check the user semaphore */
	US_LOCK,		/* lock the user semaphore */
	US_UNLOCK,		/* unlock the user semaphore */
};

#define	US_OK		0
#define	US_OWNER	US_OK
#define	US_NOTOWNER	1
#define	US_FREE		2
#define	US_ERROR	-1

#if defined(__STDC__)

int semctl(int, int, int, ...);
int semget(key_t, int, int);
int semop(int, struct sembuf *, unsigned);

#else /* Not __STDC__ */

int	semctl(), semget(), semop();

#endif /* __STDC__ */

#endif   /* _SEM_H */
