/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	pthread_exc.h,v $
 * Revision 4.2  91/09/20  04:59:38  devbld
 * Adding ODE Headers
 * 
 * $EndLog$
 */
/*
 *	@(#)$RCSfile: pthread_exc.h,v $ $Revision: 4.2 $ (DEC) $Date: 91/09/20 04:59:38 $
 */
/*
 *  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
 *	
 *	Exception Generating Pthreads Interface (ptdexc)
 *
 *  ABSTRACT:
 *
 *	External definitions for CMA's pthreads exception (ptdexc) services
 *
 *  AUTHORS:
 *
 *	Paul Curtin
 *
 *  CREATION DATE:
 * 
 *	27 August 1990
 *
 *  MODIFICATION HISTORY:
 *
 *	001	Dave Butenhof	10 October 1990
 *		Use _CMA_IMPORT_ config symbol for distinguished handles
 *	002	Paul Curtin	9 November 1990
 *		Removed _e from pthread_equal routines 
 *	003	Paul Curtin	20 November 1990
 *		Removed p from pthread in posix_pthread_attr_stacksize
 *		Added two new defines for; realtime scheduling, and signals.
 *	004	Paul Curtin	21 November 1990
 *		Swithed order of arguments to pthread_keycreate
 *	005	Paul Curtin	21 January 1991
 *		Changed *_illinst to *_illinstr to match cma.h
 *	006	Dave Butenhof	22 January 1991
 *		Fix exception names
 *	007	Paul Curtin	04 February 1991
 *		Adjusted a couple of names.
 *	008	Dave Butenhof	4 February 1991
 *		New function names
 *	009	Dave Butenhof	7 February 1991
 *		Fix name of delay function (for some reason, it was defined
 *		as "pthread_e_delay_e_np").
 *	010	Dave Butenhof	12 February 1991
 *		Change "friendly" mutex to "recursive", add "nonrecursive"
 *	011	Webb Scales	19 February 1991
 *		Add CMA scheduling symbols for Pthreads.
 *	012	Dave Butenhof	20 March 1991
 *		Remove _POSIX_PROCESS_SCHEDULING option, since we don't
 *		support it.
 *	013	Dave Butenhof	26 March 1991
 *		Move exception definitions to exc_handling.h
 *	014	Paul Curtin	24 April 1991
 *		Adding missing def for pthread_cond_wait
 *	015	Webb Scales	24 April 1991
 *		Corrected typedef for initroutine_t
 *	016	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.
 *	017	Dave Butenhof	05 June 1991
 *		Remove include of cma_px.h, which is already included by
 *		cma.h.
 *	018	Dave Butenhof	10 June 1991
 *		Create pthread_getunique_np
 */

#ifndef PTHREAD_EXC
#define PTHREAD_EXC

/*
 * 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}


/*
 *  Macros used to convert normal pthread routine calls to exception 
 *  returning routines.  This is done by including this file, pthread_exc.h,
 *  in the place of pthread.h .
 */


#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)

#define pthread_attr_create(attr) \
    ptdexc_attr_create(attr)

#define pthread_attr_delete(attr) \
    ptdexc_attr_delete(attr)

#define pthread_attr_setprio(attr,priority) \
    ptdexc_attr_setprio(attr,priority)

#define pthread_attr_getprio(attr) \
    ptdexc_attr_getprio(attr)

#define pthread_attr_setsched(attr,scheduler) \
    ptdexc_attr_setsched(attr,scheduler)

#define pthread_attr_getsched(attr) \
    ptdexc_attr_getsched(attr)

#define pthread_attr_setinheritsched(attr,inherit) \
    ptdexc_attr_setinheritsched(attr,inherit)

#define pthread_attr_getinheritsched(attr) \
    ptdexc_attr_getinheritsched(attr)

#define pthread_attr_setstacksize(attr,stacksize) \
    ptdexc_attr_setstacksize(attr,stacksize)

#define pthread_attr_getstacksize(attr) \
    ptdexc_attr_getstacksize(attr)

#define pthread_create(thread,attr,start_routine,arg) \
    ptdexc_create(thread,attr,start_routine,arg)

#define pthread_detach(thread) \
    ptdexc_detach(thread)

#define pthread_exit(status) \
    ptdexc_exit(status)

#define pthread_join(thread,status) \
    ptdexc_join(thread,status)

#define pthread_setprio(thread,priority) \
    ptdexc_setprio(thread,priority)

#define pthread_setscheduler(thread,scheduler,priority) \
    ptdexc_setscheduler(thread,scheduler,priority)

#define pthread_yield() \
    ptdexc_yield()

#define pthread_self() \
    ptdexc_self()

#define pthread_getprio(thread) \
    ptdexc_getprio(thread)

#define pthread_getscheduler(thread) \
    ptdexc_getscheduler(thread)

#define pthread_mutexattr_create(attr) \
    ptdexc_mutexattr_create(attr)

#define pthread_mutexattr_delete(attr) \
    ptdexc_mutexattr_delete(attr)

#define pthread_mutexattr_setkind_np(attr,kind) \
    ptdexc_mutexattr_setkind_np(attr,kind)

#define pthread_mutexattr_getkind_np(attr) \
    ptdexc_mutexattr_getkind_np(attr)

#define pthread_mutex_init(mutex,attr) \
    ptdexc_mutex_init(mutex,attr)

#define pthread_mutex_destroy(mutex) \
    ptdexc_mutex_destroy(mutex)

#define pthread_mutex_lock(mutex) \
    ptdexc_mutex_lock(mutex)

#define pthread_mutex_trylock(mutex) \
    ptdexc_mutex_trylock(mutex)

#define pthread_mutex_unlock(mutex) \
    ptdexc_mutex_unlock(mutex)

#define pthread_condattr_create(attr) \
    ptdexc_condattr_create(attr)

#define pthread_condattr_delete(attr) \
    ptdexc_condattr_delete(attr)

#define pthread_cond_init(cond,attr) \
    ptdexc_cond_init(cond,attr)

#define pthread_cond_destroy(cond) \
    ptdexc_cond_destroy(cond)

#define pthread_cond_broadcast(cond) \
    ptdexc_cond_broadcast(cond)

#define pthread_cond_signal(cond) \
    ptdexc_cond_signal(cond)

#define pthread_cond_wait(cond,mutex) \
    ptdexc_cond_wait(cond,mutex)

#define pthread_cond_timedwait(cond,mutex,abstime) \
    ptdexc_cond_timedwait(cond,mutex,abstime)

#define pthread_once(once_block,init_routine) \
    ptdexc_once(once_block,init_routine)

#define pthread_keycreate(key,destructor) \
    ptdexc_keycreate(key,destructor)

#define pthread_setspecific(key,value) \
    ptdexc_setspecific(key,value)

#define pthread_getspecific(key,value) \
    ptdexc_getspecific(key,value)

#define pthread_mutexattr_setkind(attr,kind) \
    ptdexc_mutexattr_setkind_np(attr,kind)

#define pthread_mutexattr_getkind(attr) \
    ptdexc_mutexattr_getkind_np(attr)

#define pthread_cancel(thread) \
    ptdexc_cancel(thread)

#define pthread_testcancel() \
    ptdexc_testcancel()

#define pthread_setasynccancel(state) \
    ptdexc_setasynccancel(state)

#define pthread_setcancel(state) \
    ptdexc_setcancel(state)

#define pthread_delay_np(interval) \
    ptdexc_delay_np(interval)

#define pthread_lock_global_np() \
    ptdexc_lock_global_np()

#define pthread_unlock_global_np() \
    ptdexc_unlock_global_np()


/*
 * 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.
 */

void
ptdexc_attr_create _CMA_PROTOTYPE_ ((
	pthread_attr_t		*attr));

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

void
ptdexc_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.
 */
void
ptdexc_attr_setprio _CMA_PROTOTYPE_ ((
	pthread_attr_t	*attr,
	int		priority));

int
ptdexc_attr_getprio _CMA_PROTOTYPE_ ((
	pthread_attr_t	attr));

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

int
ptdexc_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.
 */
void
ptdexc_attr_setinheritsched _CMA_PROTOTYPE_ ((
	pthread_attr_t	*attr,
	int		inherit));

int
ptdexc_attr_getinheritsched _CMA_PROTOTYPE_ ((
	pthread_attr_t		attr));

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

long
ptdexc_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.
 */
void
ptdexc_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.
 */
void
ptdexc_detach _CMA_PROTOTYPE_ ((
	pthread_t		*thread));

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

/* 
 * A thread can await termination of another thread and retrieve the return
 * value of the thread.
 */
void
ptdexc_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
ptdexc_setprio _CMA_PROTOTYPE_ ((
	pthread_t	thread,
	int		priority));

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

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

/*
 * Thread Information Operations
 */

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

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

/*
 * The current user_assigned scheduler algorithm of a thread can be read.
 */
int
ptdexc_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;

void
ptdexc_mutexattr_create _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	*attr));

void
ptdexc_mutexattr_delete _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	*attr));

void
ptdexc_mutexattr_setkind_np _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	*attr,
	int			kind));

int
ptdexc_mutexattr_getkind_np _CMA_PROTOTYPE_ ((
	pthread_mutexattr_t	attr));

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

void
ptdexc_mutex_destroy _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

void
ptdexc_mutex_lock _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

int
ptdexc_mutex_trylock _CMA_PROTOTYPE_ ((
	pthread_mutex_t		*mutex));

void
ptdexc_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;

void
ptdexc_condattr_create _CMA_PROTOTYPE_ ((
	pthread_condattr_t	*attr));

void
ptdexc_condattr_delete _CMA_PROTOTYPE_ ((
	pthread_condattr_t	*attr));

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

void
ptdexc_cond_destroy _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond));

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

void
ptdexc_cond_signal _CMA_PROTOTYPE_ ((
	pthread_cond_t		*cond));

/*
 * A thread can wait for a condition variable to be signalled or broadcast.
 */
void
ptdexc_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
ptdexc_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));

void
ptdexc_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
 */
void
ptdexc_keycreate _CMA_PROTOTYPE_ ((
	pthread_key_t		*key,
	pthread_destructor_t	destructor));

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

/*
 * A thread can retrieve a per-thread context value identified by a key.
 */
void
ptdexc_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.
 */

void
ptdexc_cancel _CMA_PROTOTYPE_ ((
	pthread_t	thread));

/*
 * The current thread can poll for alert delivery.
 */
void
ptdexc_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
ptdexc_setasynccancel _CMA_PROTOTYPE_ ((
	int	state));

int
ptdexc_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
ptdexc_get_expiration_np _CMA_PROTOTYPE_ ((
	struct timespec	*delta,
	struct timespec	*abstime));

extern void
ptdexc_delay_np _CMA_PROTOTYPE_ ((
	struct timespec	*interval));

extern void
ptdexc_lock_global_np _CMA_PROTOTYPE_ ((void));

extern void
ptdexc_unlock_global_np _CMA_PROTOTYPE_ ((void));

#endif
/*  DEC/CMS REPLACEMENT HISTORY, Element PTHREAD_EXC.H */
/*  *20   10-JUN-1991 19:59:27 SCALES "Convert to stream format for ULTRIX build" */
/*  *19   10-JUN-1991 19:22:48 BUTENHOF "Fix the sccs headers" */
/*  *18   10-JUN-1991 18:25:49 SCALES "Add sccs headers for Ultrix" */
/*  *17   10-JUN-1991 14:13:08 BUTENHOF "Add macro to extract thread sequence #" */
/*  *16    5-JUN-1991 17:32:23 BUTENHOF "On UNIX platforms, most headers are in dce/" */
/*  *15   29-MAY-1991 17:02:30 BUTENHOF "Currently on OSF/1 based system, no priority" */
/*  *14   24-APR-1991 18:43:52 SCALES "Correct definition of pthread_initroutine_t" */
/*  *13   24-APR-1991 12:21:53 CURTIN "added a missing definition" */
/*  *12    1-APR-1991 18:10:37 BUTENHOF "Fix up exceptions" */
/*  *11   21-MAR-1991 09:27:04 BUTENHOF "" */
/*  *10   19-FEB-1991 22:11:40 SCALES "Add scheduling symbols" */
/*  *9    13-FEB-1991 17:55:01 BUTENHOF "Change mutex attribute name symbols" */
/*  *8    12-FEB-1991 23:10:06 BUTENHOF "Recursive/nonrecursive mutexes" */
/*  *7    12-FEB-1991 01:29:47 BUTENHOF "Fix name of delay function" */
/*  *6     5-FEB-1991 01:00:13 BUTENHOF "Change pthread exc interface names" */
/*  *5     4-FEB-1991 13:56:15 CURTIN "Changed a couple of names" */
/*  *4    24-JAN-1991 00:35:44 BUTENHOF "Exception changes" */
/*  *3    21-JAN-1991 13:26:59 CURTIN "changed *_illinst to *_illinstr" */
/*  *2    28-DEC-1990 00:04:55 BUTENHOF "Change exception names" */
/*  *1    12-DEC-1990 21:48:47 BUTENHOF "P1003.4a support" */
/*  DEC/CMS REPLACEMENT HISTORY, Element PTHREAD_EXC.H */
