/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	pthread.h,v $
 * Revision 4.2  91/09/20  04:59:24  devbld
 * Adding ODE Headers
 * 
 * $EndLog$
 */
/*
 *	@(#)$RCSfile: pthread.h,v $ $Revision: 4.2 $ (DEC) $Date: 91/09/20 04:59:24 $
 */
/*
 *  Copyright (c) 1990, 1991 by
 *  Digital Equipment Corporation, Maynard Massachusetts.
 *  All rights reserved.
 *
 *  This software is furnished under a license and may be used and  copied
 *  only  in  accordance  with  the  terms  of  such  license and with the
 *  inclusion of the above copyright notice.  This software or  any  other
 *  copies  thereof may not be provided or otherwise made available to any
 *  other person.  No title to and ownership of  the  software  is  hereby
 *  transferred.
 *
 *  The information in this software is subject to change  without  notice
 *  and  should  not  be  construed  as  a commitment by DIGITAL Equipment
 *  Corporation.
 *
 *  DIGITAL assumes no responsibility for the use or  reliability  of  its
 *  software on equipment which is not supplied by DIGITAL.
 */

/*
 *  FACILITY:
 *
 *	Common Multithread Architecture (CMA) services; POSIX 1003.4 interface
 *
 *  ABSTRACT:
 *
 *	External definitions for CMA's pthreads services
 *
 *  AUTHORS:
 *
 *	Dave Butenhof
 *
 *  CREATION DATE:
 * 
 *	20 February 1990
 *
 *  MODIFICATION HISTORY:
 *
 *	001	Dave Butenhof	6 March 1990
 *		Some PTHREAD constants are defined in terms of CMA enums;
 *		they need to be cast to (int) to prevent complaints by some
 *		compilers.
 *	002	Dave Butenhof	2 May 1990
 *		Implement cancel and push/pop handlers (on top of CMA
 *		exception handling and alerts).
 *	003	Dave Butenhof	18 May 1990
 *		Change pthread_cond_timedwait to use struct timespec.
 *	004	Dave Butenhof	12 June 1990
 *		Add pthread_delay_np and pthread_get_expiration_np.
 *	005	Dave Butenhof	22 June 1990
 *		Update interface to 1003.4a/D3 (May 11, 1990).  This includes
 *		changing synchronization variable parameters from "value" to
 *		"reference", but does not include degenerating attributes
 *		objects to public structures.  It also does not include the
 *		new event operations.
 *	006	Dave Butenhof	27 June 1990
 *		Clean up some, and implement "pthread_equal_np" macro.
 *	007	Dave Butenhof	29 June 1990
 *		Change interface to pthread_get_expiration_np (an in and an
 *		out instead of just one modify).
 *	008	Dave Butenhof	2 July 1990
 *		Add constants and functions for controlling whether mutex
 *		locks can nest within a thread ("friendly mutexes").
 *	009	Dave Butenhof	27 July 1990
 *		Fix pthread_equal
 *	010	Dave Butenhof	5 October 1990
 *		Implement pthread_lock_global_np and
 *		pthread_unlock_global_np.
 *	011	Dave Butenhof	9 October 1990
 *		Use new _CMA_IMPORT_ symbol to import the pthread
 *		distinguished handled.
 *	012	Paul Curtin	20 November 1990
 *		Removed p from pthread in posix_pthread_attr_stacksize.
 *		Added two new defines for; realtime scheduling, and signals.
 *	013	Paul Curtin	21 November 1990
 *		Switch order of arguments to pthread_keycreate
 *	014	Dave Butenhof	12 February 1991
 *		Change "friendly" mutex to "recursive", add "nonrecursive"
 *	015	Webb Scales	19 February 1991
 *		Add CMA scheduling symbols for Pthreads.
 *	016	Dave Butenhof	20 March 1991
 *		Remove _POSIX_PROCESS_SCHEDULING option, since we don't
 *		support it.
 *	017	Dave Butenhof	29 May 1991
 *		Remove the realtime scheduling option under OSF/1 when
 *		using kernel threads, since it doesn't (yet) support POSIX
 *		scheduling for Mach threads.
 *	018	Dave Butenhof	05 June 1991
 *		Remove include of cma_px.h, which is already included by
 *		cma.h.
 *	019	Dave Butenhof	10 June 1991
 *		Create pthread_getunique_np
 */

#ifndef PTHREAD
#define PTHREAD

/*
 * The implementation makes these basic decisions
 */

#include <cma.h>

#define _POSIX_THREADS				1
#define _POSIX_THREAD_ATTR_STACKSIZE		1
#if _CMA_KTHREADS_ != _CMA__MACH
# define _POSIX_THREADS_REALTIME_SCHEDULING	1
#endif
#define	_POSIX_THREADS_PER_PROCESS_SIGNALS_1	1

/*
 * Implement push and pop for cancellation handlers, using TRY and ENDTRY
 */

#define pthread_cleanup_push(routine,arg)	\
    { \
    pthread_cleanup_t _XXX_proc = (pthread_cleanup_t)(routine); \
    pthread_addr_t _XXX_arg = (pthread_addr_t)(arg); \
    int _XXX_completed = 0; \
    TRY {

#define pthread_cleanup_pop(execute)	\
    _XXX_completed = 1;} \
    FINALLY { \
	if ((! _XXX_completed) || (execute)) _XXX_proc (_XXX_arg);} \
    ENDTRY}

#define pthread_equal_np(thread1,thread2) \
    (((thread1).field1 == (thread2).field1) \
    && ((thread1).field2 == (thread2).field2))

#define pthread_equal(thread1,thread2) \
    (((thread1).field1 == (thread2).field1) \
    && ((thread1).field2 == (thread2).field2))

#define pthread_getunique_np(handle) \
    (((unsigned int)((pthread_t *)handle)->field2) & 0xffff)

/*
 * Sample decisions for the environment types
 */

typedef	cma_t_key		pthread_key_t;

typedef cma_t_address		pthread_addr_t;

typedef void (*pthread_cleanup_t) _CMA_PROTOTYPE_ ((pthread_addr_t arg));

/*
 * Sample decision for a one-time initialization control block and its
 * initialization macro.
 *
 * Declare a one time initialization control block as:
 *
 *	static pthread_once_t	block = pthread_once_init;
 */
typedef cma_t_once	pthread_once_t;

#define pthread_once_init	cma_once_init

#define CANCEL_ON	1
#define CANCEL_OFF	0

/*
 * The following are the portable pthread definitions
 */

/*
 * Operations on Handles
 */

/*
 * Operations on attributes objects
 */

typedef cma_t_attr	pthread_attr_t;

/*
 * An attributes object is created to specify the attributes of other CMA
 * objects that will be created.
 */

int
pthread_attr_create _CMA_PROTOTYPE_ ((
	pthread_attr_t		*attr));

/*
 * An attributes object can be deleted when it is no longer needed.
 */

int
pthread_attr_delete _CMA_PROTOTYPE_ ((
	pthread_attr_t		*attr));

/*
 * Operations on threads
 */

typedef cma_t_thread		pthread_t;
typedef cma_t_start_routine	pthread_startroutine_t;

#define PTHREAD_INHERIT_SCHED	((int)cma_c_sched_inherit)
#define PTHREAD_DEFAULT_SCHED	((int)cma_c_sched_use_default)

#define SCHED_FIFO		((int)cma_c_sched_fifo)
#define SCHED_RR		((int)cma_c_sched_rr)
#define SCHED_FG_NP		((int)cma_c_sched_throughput)
#define SCHED_BG_NP		((int)cma_c_sched_background)
#define SCHED_OTHER		((int)cma_c_sched_throughput)

#define PRI_FIFO_MIN		((int)cma_c_prio_fifo_min)
#define PRI_FIFO_MAX		((int)cma_c_prio_fifo_max)
#define PRI_RR_MIN		((int)cma_c_prio_rr_min)
#define PRI_RR_MAX		((int)cma_c_prio_rr_max)
#define PRI_FG_MIN_NP		((int)cma_c_prio_through_min)
#define PRI_FG_MAX_NP		((int)cma_c_prio_through_max)
#define PRI_BG_MIN_NP		((int)cma_c_prio_back_min)
#define PRI_BG_MAX_NP		((int)cma_c_prio_back_max)
#define PRI_OTHER_MIN		((int)cma_c_prio_through_min)
#define PRI_OTHER_MAX		((int)cma_c_prio_through_max)

/*
 * Operations to define thread creation attributes
 */

/*
 * Set or obtain the default thread priority.
 */
int
pthread_attr_setprio _CMA_PROTOTYPE_ ((
	pthread_attr_t	*attr,
	int		priority));

int
pthread_attr_getprio _CMA_PROTOTYPE_ ((
	pthread_attr_t	attr));

/*
 * Set or obtain the default scheduling algorithm
 */
int
pthread_attr_setsched _CMA_PROTOTYPE_ ((
	pthread_attr_t	*attr,
	int		scheduler));

int
pthread_attr_getsched _CMA_PROTOTYPE_ ((
	pthread_attr_t	attr));

/*
 * Set or obtain whether a thread will use the default scheduling attributes,
 * or inherit them from the creating thread.
 */
int
pthread_attr_setinheritsched _CMA_PROTOTYPE_ ((
	pthread_attr_t	*attr,
	int		inherit));

int
pthread_attr_getinheritsched _CMA_PROTOTYPE_ ((
	pthread_attr_t		attr));

/*
 * Set or obtain the default stack size
 */
int
pthread_attr_setstacksize _CMA_PROTOTYPE_ ((
	pthread_attr_t	*attr,
	long		stacksize));

long
pthread_attr_getstacksize _CMA_PROTOTYPE_ ((
	pthread_attr_t	attr));

/*
 * The following procedures can be used to control thread creation,
 * termination and deletion.
 */

/*
 * To create a thread object and runnable thread, a routine must be specified
 * as the new thread's start routine.  An argument may be passed to this
 * routine, as an untyped address; an untyped address may also be returned as
 * the routine's value.  An attributes object may be used to specify details
 * about the kind of thread being created.
 */
int
pthread_create _CMA_PROTOTYPE_ ((
	pthread_t		*thread,
	pthread_attr_t		attr,
	pthread_startroutine_t	start_routine,
	pthread_addr_t		arg));

/*
 * A thread object may be "detached" to specify that the return value and
 * completion status will not be requested.
 */
int
pthread_detach _CMA_PROTOTYPE_ ((
	pthread_t		*thread));

/* 
 * A thread may terminate it's own execution.
 */
void
pthread_exit _CMA_PROTOTYPE_ ((
	pthread_addr_t 		status));

/* 
 * A thread can await termination of another thread and retrieve the return
 * value of the thread.
 */
int
pthread_join _CMA_PROTOTYPE_ ((
	pthread_t		thread,
	pthread_addr_t		*status));

/*
 * Thread Scheduling Operations
 */

/*
 * The current user_assigned priority of a thread can be changed.
 */
int
pthread_setprio _CMA_PROTOTYPE_ ((
	pthread_t	thread,
	int		priority));

/*
 * The current user_assigned scheduler algorithm of a thread can be changed.
 */
int
pthread_setscheduler _CMA_PROTOTYPE_ ((
	pthread_t	thread,
	int		scheduler,
	int		priority));

/*
 * A thread may tell the scheduler that its processor can be made available.
 */
void
pthread_yield _CMA_PROTOTYPE_ ((void));

/*
 * Thread Information Operations
 */

/*
 * A thread may obtain a copy of its own thread handle.
 */
pthread_t
pthread_self _CMA_PROTOTYPE_ ((void));

/*
 * The current user_assigned priority of a thread can be read.
 */
int
pthread_getprio _CMA_PROTOTYPE_ ((
	pthread_t	thread));

/*
 * The current user_assigned scheduler algorithm of a thread can be read.
 */
int
pthread_getscheduler _CMA_PROTOTYPE_ ((
	pthread_t	thread));

/*
 * Operations on Mutexes
 */

#define MUTEX_FAST_NP		0
#define MUTEX_RECURSIVE_NP	1
#define MUTEX_NONRECURSIVE_NP	2

typedef cma_t_attr	pthread_mutexattr_t;
typedef	cma_t_mutex	pthread_mutex_t;

int
pthread_mutexattr_create _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	*attr));

int
pthread_mutexattr_delete _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	*attr));

int
pthread_mutexattr_setkind_np _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	*attr,
	int			kind));

int
pthread_mutexattr_getkind_np _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	attr));

/* 
 * The following routines create, delete, lock and unlock mutexes.
 */
int
pthread_mutex_init _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex,
	pthread_mutexattr_t	attr));

int
pthread_mutex_destroy _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

int
pthread_mutex_lock _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

int
pthread_mutex_trylock _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

int
pthread_mutex_unlock _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

/*
 * Operations on condition variables
 */

typedef cma_t_attr	pthread_condattr_t;
typedef cma_t_cond	pthread_cond_t;

int
pthread_condattr_create _CMA_PROTOTYPE_ ((
	pthread_condattr_t	*attr));

int
pthread_condattr_delete _CMA_PROTOTYPE_ ((
	pthread_condattr_t	*attr));

/*
 * A thread can create and delete condition variables.
 */
int
pthread_cond_init _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond,
	pthread_condattr_t	attr));

int
pthread_cond_destroy _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond));

/*
 * A thread can signal to and broadcast on a condition variable.
 */
int
pthread_cond_broadcast _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond));

int
pthread_cond_signal _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond));

/*
 * A thread can wait for a condition variable to be signalled or broadcast.
 */
int
pthread_cond_wait _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond,
	pthread_mutex_t		*mutex));

/*
 * Operations for timed waiting
 */

/*
 * A thread can perform a timed wait on a condition variable.
 */
int
pthread_cond_timedwait _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond,
	pthread_mutex_t		*mutex,
	struct timespec		*abstime));

/*
 * Operations for client initialization.
 */

typedef void (*pthread_initroutine_t) _CMA_PROTOTYPE_ ((void));

int
pthread_once _CMA_PROTOTYPE_ ((
	pthread_once_t		*once_block,
	pthread_initroutine_t	init_routine));

/*
 * Operations for per-thread context
 */

typedef cma_t_destructor	pthread_destructor_t;

/*
 * A unique per-thread context key can be obtained for the process
 */
int
pthread_keycreate _CMA_PROTOTYPE_ ((
	pthread_key_t		*key,
	pthread_destructor_t	destructor));

/*
 * A thread can set a per-thread context value identified by a key.
 */
int
pthread_setspecific _CMA_PROTOTYPE_ ((
	pthread_key_t	key,
	pthread_addr_t	value));

/*
 * A thread can retrieve a per-thread context value identified by a key.
 */
int
pthread_getspecific _CMA_PROTOTYPE_ ((
	pthread_key_t	key,
	pthread_addr_t	*value));

/*
 * Operations for alerts.
 */

/*
 * The current thread can request that a thread terminate it's execution.
 */

int
pthread_cancel _CMA_PROTOTYPE_ ((
	pthread_t	thread));

/*
 * The current thread can poll for alert delivery.
 */
void
pthread_testcancel _CMA_PROTOTYPE_ ((void));

/*
 * The current thread can enable or disable alert delivery (PTHREAD
 * "cancels"); it can control "general cancelability" (CMA "defer") or
 * just "asynchronous cancelability" (CMA "asynch disable").
 */
int
pthread_setasynccancel _CMA_PROTOTYPE_ ((
	int	state));

int
pthread_setcancel _CMA_PROTOTYPE_ ((
	int	state));

_CMA_IMPORT_ pthread_attr_t		pthread_attr_default;
_CMA_IMPORT_ pthread_mutexattr_t	pthread_mutexattr_default;
_CMA_IMPORT_ pthread_condattr_t		pthread_condattr_default;

/*
 * Define nonportable extensions
 */

extern int
pthread_get_expiration_np _CMA_PROTOTYPE_ ((
	struct timespec	*delta,
	struct timespec	*abstime));

extern int
pthread_delay_np _CMA_PROTOTYPE_ ((
	struct timespec	*interval));

extern void
pthread_lock_global_np _CMA_PROTOTYPE_ ((void));

extern void
pthread_unlock_global_np _CMA_PROTOTYPE_ ((void));

#endif
/*  DEC/CMS REPLACEMENT HISTORY, Element PTHREAD.H */
/*  *12   10-JUN-1991 19:59:15 SCALES "Convert to stream format for ULTRIX build" */
/*  *11   10-JUN-1991 19:22:44 BUTENHOF "Fix the sccs headers" */
/*  *10   10-JUN-1991 18:25:45 SCALES "Add sccs headers for Ultrix" */
/*  *9    10-JUN-1991 14:13:03 BUTENHOF "Add macro to extract thread sequence #" */
/*  *8     5-JUN-1991 17:32:16 BUTENHOF "On UNIX platforms, most headers are in dce/" */
/*  *7    29-MAY-1991 17:02:25 BUTENHOF "Currently on OSF/1 based system, no priority" */
/*  *6     1-APR-1991 18:10:30 BUTENHOF "Add pthread_signal_to_cancel_np()" */
/*  *5    21-MAR-1991 09:26:59 BUTENHOF "" */
/*  *4    19-FEB-1991 22:11:29 SCALES "Add scheduling symbols" */
/*  *3    13-FEB-1991 17:54:56 BUTENHOF "Change mutex attribute name symbols" */
/*  *2    12-FEB-1991 23:10:02 BUTENHOF "Recursive/nonrecursive mutexes" */
/*  *1    12-DEC-1990 21:48:44 BUTENHOF "P1003.4a support" */
/*  DEC/CMS REPLACEMENT HISTORY, Element PTHREAD.H */
