/*
 * $Header: /smsa/bsd:include/sys/sem.h:bsd  1.6  $
 * $Source: /smsa/bsd:include/sys/sem.h: $
 *
 * Copyright (c) 1988 Acorn Computers Ltd., Cambridge, England
 *
 */
#ifndef	__sys_sem_h
#define	__sys_sem_h

/*
**	IPC Semaphore Facility.
*/

#ifndef	__sys_types_h
#include "types.h"
#endif
#ifndef __sys_ipc_h
#include "ipc.h"
#endif

/*
**	Implementation Constants and system limits.
*/

#ifdef	_KERNEL
#define	PSEM	(PZERO + 2)	/* sleep priority */
#endif

/* The implementation assumes all these limits are small */

#define NSEMID		5	/* Max semaphore ids in system */
#define NSEMSINSET	5	/* Max semaphores in one set */
#define SEMMAXOPS	5	/* Max ops in one semop() call */
#define SEMMAXVAL	1000	/* Limit on semaphore value */
#define SEMMAXADJ	1000	/* un_semadj limited to + or - this */
#define NUNDOPERPROC	5	/* Max undo entries per process */
#define NUNDO		5	/* Max processes with undo structures */ 

/*
**	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 structure for each semaphore in the system.
*/
struct sem {
	ushort	semval;		/* semaphore text map address */
	pid_t	sempid;		/* pid of last operation */
	ushort	semncnt;	/* # awaiting semval > cval */
	ushort	semzcnt;	/* # awaiting semval = 0 */
};

/*
**	There is one semaphore id data structure for each set of semaphores
**	in the system. Since the limits specified in the SVID are
**	  1) Number of semid_ds structures in system
**	  2) Number of semaphores per semid
**	(with no separate limit on total semaphores in system),
**	we simply include a maximum-size array of semaphores in each
**	semid_ds structure.
*/

struct semid_ds {
	struct ipc_perm	sem_perm;	/* operation permission struct */
	ushort		sem_nsems;	/* # of semaphores in set */
	time_t		sem_otime;	/* last semop time */
	time_t		sem_ctime;	/* last change time */
	/* End of fields defined in SVID */
	struct sem	sem_sems[NSEMSINSET];	/* set of semaphores */
};

/*
**	An undo structure is allocated to each process which requests
**      one (up to the NUNDO limit).
*/

struct sem_undo {
  	int un_pid;	/* Process which owns this undo struct (-1 if none) */
	struct undo {
		int	un_semadj;	/* Adjustment value */
		/* Unused slots have un_semadj set to zero */
		int	un_semid;	/* Semaphore id */
		int	un_semnum;	/* Semaphore number */
	} un_ent[NUNDOPERPROC];	/* undo entries */
};

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

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

#ifndef	_KERNEL
union semun 
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};
extern int semctl (int __semid, int __semnum, int __cmd, union semun __arg);
extern int semget (key_t __key, int __nsems, int __semflg);
extern int semop (int __semid, struct sembuf *__sops, unsigned nsops);
#endif

#endif/*__sys_sem_h*/

/* EOF sem.h */
