/*
 * $Id: pthread.h,v 1.14 2000/10/27 04:05:31 k-abe Exp $
 *
 * This file is part of PTL, Portable Thread Library.
 *
 * Copyright (C) 1997-2000 Kota Abe
 *
 */

#ifndef __PTL_PTHREAD_H__
#define __PTL_PTHREAD_H__

#include <sys/pthread-init.h>
#include <sys/types.h>			/* size_t, time_t */
#include <sys/pthread-cdecl.h>
#include <sys/pthread-extsym.h>
#include <time.h>
#include <sched.h>
#include <unistd.h>
#include <stdio.h>

/* This is PTL, Portable Thread Library */
#define	__PTL__

__PTL_BEGIN_DECLS

/****************************************************************
 *
 *	3.1.3  Register Fork Handlers
 *
 ****************************************************************/

extern int pthread_atfork __PTL_P((void (*)__PTL_NOARGS,
				   void (*)__PTL_NOARGS,
				   void (*)__PTL_NOARGS));


/****************************************************************
 *
 *	11.3.1  Mutex Initialization Attributes
 *
 ****************************************************************/

extern int pthread_mutexattr_init __PTL_P((pthread_mutexattr_t*));
extern int pthread_mutexattr_destroy __PTL_P((pthread_mutexattr_t*));
extern int pthread_mutexattr_setpshared __PTL_P((pthread_mutexattr_t*,
						 int));
extern int pthread_mutexattr_getpshared __PTL_P((const pthread_mutexattr_t*,
						 int*));


/****************************************************************
 *
 *	11.3.2  Initializing and Destroying a Mutex
 *
 ****************************************************************/

extern int pthread_mutex_init __PTL_P((pthread_mutex_t*,
					  const pthread_mutexattr_t*));
extern int pthread_mutex_destroy __PTL_P((pthread_mutex_t*));


/****************************************************************
 *
 *	11.3.3  Locking and Unlocking a Mutex
 *
 ****************************************************************/

extern int pthread_mutex_lock __PTL_P((pthread_mutex_t*));
extern int _pthread_mutex_lock __PTL_P((pthread_mutex_t*,
					const char*, const char*, int));
extern int pthread_mutex_trylock __PTL_P((pthread_mutex_t*));
extern int pthread_mutex_unlock __PTL_P((pthread_mutex_t*));

#ifndef PTL_NO_RENAME
# define pthread_mutex_lock(mutex) \
	_pthread_mutex_lock(mutex, __FILE__, __FUNCTION__, __LINE__)
#endif

/****************************************************************
 *
 *	11.4.1  Condition Variable Initialization Attributes
 *
 ****************************************************************/

extern int pthread_condattr_init __PTL_P((pthread_condattr_t*));
extern int pthread_condattr_destroy __PTL_P((pthread_condattr_t*));
extern int pthread_condattr_setpshared __PTL_P((pthread_condattr_t*, int));
extern int pthread_condattr_getpshared __PTL_P((const pthread_condattr_t*,
						int*));


/****************************************************************
 *
 *	11.4.2  Initializing and Destroying Condition Variables
 *
 ****************************************************************/

extern int pthread_cond_init __PTL_P((pthread_cond_t*,
				      const pthread_condattr_t*));
extern int pthread_cond_destroy __PTL_P((pthread_cond_t*));


/****************************************************************
 *
 *	11.4.3  Broadcasting and Signaling a Condition
 *
 ****************************************************************/

extern int pthread_cond_broadcast __PTL_P((pthread_cond_t *));
extern int pthread_cond_signal __PTL_P((pthread_cond_t*));


/****************************************************************
 *
 *	11.4.4  Waiting on a Condition
 *
 ****************************************************************/

extern int pthread_cond_wait __PTL_P((pthread_cond_t*, pthread_mutex_t*));
extern int _pthread_cond_wait __PTL_P((pthread_cond_t*, pthread_mutex_t*,
				       const char*, const char*, int));
extern int pthread_cond_timedwait __PTL_P((pthread_cond_t*, pthread_mutex_t*,
					   const struct timespec*));
extern int _pthread_cond_timedwait __PTL_P((pthread_cond_t*, pthread_mutex_t*,
					    const struct timespec*,
					    const char*, const char*, int));

#ifndef PTL_NO_RENAME
# define pthread_cond_wait(cond, mutex) \
	_pthread_cond_wait(cond, mutex, __FILE__, __FUNCTION__, __LINE__)
# define pthread_cond_timedwait(cond, mutex, timespec)		\
	_pthread_cond_timedwait(cond, mutex, timespec, \
				__FILE__, __FUNCTION__, __LINE__)
#endif /*PTL_NO_RENAME*/

/****************************************************************
 *
 *	13.5.1  Thread Scheduling Functions
 *
 ****************************************************************/

extern int pthread_attr_setscope __PTL_P((pthread_attr_t*, int));
extern int pthread_attr_getscope __PTL_P((const pthread_attr_t*, int*));
extern int pthread_attr_setinheritsched __PTL_P((pthread_attr_t*, int));
extern int pthread_attr_getinheritsched __PTL_P((const pthread_attr_t*, int*));
extern int pthread_attr_setschedpolicy __PTL_P((pthread_attr_t*, int));
extern int pthread_attr_getschedpolicy __PTL_P((const pthread_attr_t*, int*));
extern int pthread_attr_setschedparam __PTL_P((pthread_attr_t*,
					       const struct sched_param*));
extern int pthread_attr_getschedparam __PTL_P((const pthread_attr_t*,
					       struct sched_param*));

/* Contention scope */
#define PTHREAD_EXPLICIT_SCHED	0
#define PTHREAD_INHERIT_SCHED	1

/* Inheritsched */
#define PTHREAD_SCOPE_PROCESS	0
#define PTHREAD_SCOPE_SYSTEM	2


/****************************************************************
 *
 *	13.5.2  Dynamic Thread Scheduling Parameters Access
 *
 ****************************************************************/

extern int pthread_getschedparam __PTL_P((pthread_t, int*,
					  struct sched_param *param));
extern int pthread_setschedparam __PTL_P((pthread_t, int,
					  const struct sched_param *param));


/****************************************************************
 *
 *	13.6.1  Mutex Initialization Scheduling Attributes
 *
 ****************************************************************/

extern int pthread_mutexattr_setprotocol __PTL_P((pthread_mutexattr_t*, int));
extern int pthread_mutexattr_getprotocol __PTL_P((const pthread_mutexattr_t*,
						  int*)); 
extern int pthread_mutexattr_setprioceiling __PTL_P((pthread_mutexattr_t*,
						     int));
extern int pthread_mutexattr_getprioceiling __PTL_P((const pthread_mutexattr_t*,
						     int*));

/* Mutex protocols */
#define PTHREAD_PRIO_NONE	1
#define PTHREAD_PRIO_INHERIT	2
#define PTHREAD_PRIO_PROTECT	3


/****************************************************************
 *
 *	13.6.2  Change the Priority Ceiling of a Mutex
 *
 ****************************************************************/

extern int pthread_mutex_setprio_ceiling __PTL_P((pthread_mutex_t*,
						  int, int*));
extern int pthread_mutex_getprio_ceiling __PTL_P((pthread_mutex_t*, int*));


/****************************************************************
 *
 *	16.2.1  Thread Creation Attributes
 *
 ****************************************************************/

extern int pthread_attr_init __PTL_P((pthread_attr_t*));
extern int pthread_attr_destroy __PTL_P((pthread_attr_t*));
extern int pthread_attr_setstacksize __PTL_P((pthread_attr_t*, size_t));
extern int pthread_attr_getstacksize __PTL_P((const pthread_attr_t*, size_t*));
extern int pthread_attr_setstackaddr __PTL_P((pthread_attr_t*, void*));
extern int pthread_attr_getstackaddr __PTL_P((const pthread_attr_t*, void**));
extern int pthread_attr_setdetachstate __PTL_P((pthread_attr_t*, int));
extern int pthread_attr_getdetachstate __PTL_P((const pthread_attr_t*, int*));
extern int pthread_attr_setstackprop_np __PTL_P((pthread_attr_t*, int));
extern int pthread_attr_getstackprop_np __PTL_P((const pthread_attr_t*, int*));
extern int pthread_attr_setsuspended_np __PTL_P((pthread_attr_t*, int));
extern int pthread_attr_getsuspended_np __PTL_P((const pthread_attr_t*, int*));

/* detachstate */
#define PTHREAD_CREATE_JOINABLE		0
#define PTHREAD_CREATE_DETACHED		4

/* suspendstate */
#define PTHREAD_CREATE_NOT_SUSPENDED_NP	0
#define PTHREAD_CREATE_SUSPENDED_NP	8

/* stack property (bitwise) */
#define PTHREAD_STACK_NONE_NP		0x0
#define PTHREAD_STACK_SAFE_NP		0x1
#define PTHREAD_STACK_EXTENSIBLE_NP	0x2


/****************************************************************
 *
 *	16.2.2  Thread Creation
 *
 ****************************************************************/

extern int pthread_create __PTL_P((pthread_t*, const pthread_attr_t*,
				   _pthread_any_t (*)__PTL_P((_pthread_any_t)),
				   _pthread_any_t));


/****************************************************************
 *
 *	16.2.3  Wait for Thread Termination
 *
 ****************************************************************/

extern int pthread_join __PTL_P((pthread_t, _pthread_any_t*));
extern int _pthread_join __PTL_P((pthread_t, _pthread_any_t*,
				  const char*, const char*, int));

#ifndef PTL_NO_RENAME
# define pthread_join(thread, status) \
	_pthread_join(thread, status, __FILE__, __FUNCTION__, __LINE__)
#endif /*PTL_NO_RENAME*/

/****************************************************************
 *
 *	16.2.4  Detaching a Thread
 *
 ****************************************************************/

extern int pthread_detach __PTL_P((pthread_t));


/****************************************************************
 *
 *	16.2.5  Thread Termination
 *
 ****************************************************************/

extern void pthread_exit __PTL_P((_pthread_any_t)) __PTL_NORET;


/****************************************************************
 *
 *	16.2.6  Get Thread ID
 *
 ****************************************************************/

extern pthread_t pthread_self __PTL_NOARGS;


/****************************************************************
 *
 *	16.2.7  Compare Thread IDs
 *
 ****************************************************************/

extern int pthread_equal __PTL_P((pthread_t, pthread_t));


/****************************************************************
 *
 *	16.2.8  Dynamic Package Initialization
 *
 ****************************************************************/

extern int pthread_once __PTL_P((pthread_once_t*, void (*)(void)));
extern int pthread_first_np __PTL_P((pthread_once_t*));
extern void pthread_first_done_np __PTL_P((pthread_once_t*));


/****************************************************************
 *
 *	17.1.1  Thread-Specific Data Key Creation
 *
 ****************************************************************/

extern int pthread_key_create __PTL_P((pthread_key_t*,
				       void (*)__PTL_P((_pthread_any_t))));


/****************************************************************
 *
 *	17.1.2  Thread-Specific Data Management
 *
 ****************************************************************/

extern int pthread_setspecific __PTL_P((pthread_key_t, const _pthread_any_t));
extern _pthread_any_t pthread_getspecific __PTL_P((pthread_key_t));


/****************************************************************
 *
 *	17.1.3  Thread-Specific Data Key Deletion
 *
 ****************************************************************/

extern int pthread_key_delete __PTL_P((pthread_key_t));


/****************************************************************
 *
 *	18.1.3  Thread Cancellation Cleanup Handler
 *
 ****************************************************************/

/* exit status value from canceled thread */
#define PTHREAD_CANCELED ((_pthread_any_t)-1)


/****************************************************************
 *
 *	18.2.1  Canceling Execution of a Thread
 *
 ****************************************************************/

extern int pthread_cancel __PTL_P((pthread_t));


/****************************************************************
 *
 *	18.2.2  Setting Cancelability State
 *
 ****************************************************************/

extern int pthread_setcancelstate __PTL_P((int, int*));
extern int pthread_setcanceltype __PTL_P((int, int*));
extern void pthread_testcancel __PTL_NOARGS;

/* cancelability state */
#define PTHREAD_CANCEL_ENABLE		1
#define PTHREAD_CANCEL_DISABLE		2

/* cancelability type */
#define PTHREAD_CANCEL_DEFERRED		3
#define PTHREAD_CANCEL_ASYNCHRONOUS	4


/****************************************************************
 *
 *	18.2.3  Establishing Cancellation Handlers
 *
 ****************************************************************/

/* structure to record cleanup stack */
struct _pthread_handler_rec {
    struct _pthread_handler_rec	*next;
    void			(*rtn)__PTL_P((_pthread_any_t));
    void			*arg;
    short			inlined;
};

extern struct _pthread_handler_rec **_pthread_cleanup_header __PTL_NOARGS;

#define pthread_cleanup_push(routine,argument) {			\
    struct _pthread_handler_rec	__cleanup_handler, **__head;		\
    __cleanup_handler.inlined = 1;					\
    __cleanup_handler.rtn = routine;					\
    __cleanup_handler.arg = argument;					\
    __head = _pthread_cleanup_header();					\
    __cleanup_handler.next = *__head;					\
    *__head = &__cleanup_handler;

#define pthread_cleanup_pop(ex)						\
    *__head = __cleanup_handler.next;					\
    if (ex) (*__cleanup_handler.rtn)(__cleanup_handler.arg);		\
}

extern int pthread_cleanup_pop_f_np __PTL_P((int));
extern int pthread_cleanup_push_f_np __PTL_P((void(*)__PTL_P((_pthread_any_t)),
					      _pthread_any_t));


/****************************************************************
 *
 *	PTL Extension
 *
 ****************************************************************/

/****************************************************************
 *
 *	Suspend Execution of a Thread
 *
 ****************************************************************/

extern int pthread_suspend_np __PTL_P((pthread_t));
extern int pthread_resume_np __PTL_P((pthread_t));


/****************************************************************
 *
 *	Set process exit code
 *
 ****************************************************************/

extern int pthread_set_exit_status_np __PTL_P((int));


/****************************************************************
 *
 *	Name to a Threads, Mutexes, Condition Variables
 *
 ****************************************************************/

extern int pthread_setname_np __PTL_P((pthread_t, const char*));
extern int pthread_getname_np __PTL_P((pthread_t, char**));
extern int pthread_mutex_setname_np __PTL_P((pthread_mutex_t*, const char*));
extern int pthread_mutex_getname_np __PTL_P((pthread_mutex_t*, char**));
extern int pthread_cond_setname_np __PTL_P((pthread_cond_t*, const char*));
extern int pthread_cond_getname_np __PTL_P((pthread_cond_t*, char**));


/****************************************************************
 *
 *	Get # of Waiters of Mutex, Condition Variables
 *
 ****************************************************************/

extern int pthread_mutex_waiters_np __PTL_P((pthread_mutex_t*));
extern int pthread_cond_waiters_np __PTL_P((pthread_cond_t*));


/****************************************************************
 *
 *	Trace Thread Execution Behavior
 *
 ****************************************************************/

/* weakly supported */
extern int pthread_log_np();


/****************************************************************
 *
 *	Thread Stack PreAllocation
 *
 ****************************************************************/

extern int pthread_alloc_stack_cache_np __PTL_P((pthread_attr_t*, int));

extern int	pthread_stack_expansion_np;


/****************************************************************
 *
 *	I/O
 *
 ****************************************************************/

extern void pthread_poll_interval_np __PTL_P((const struct timespec *,
					      struct timespec *));


/****************************************************************
 *
 *	Thread Specific Alarm
 *
 ****************************************************************/

extern unsigned int pthread_alarm_np __PTL_P((unsigned int));
extern unsigned int pthread_ualarm_np __PTL_P((unsigned int, unsigned int));


/****************************************************************
 *
 *	for Debugging support
 *
 ****************************************************************/

extern void pthread_debug_printf_np __PTL_P((const char *, ...));
extern void pthread_debug_pdb_np __PTL_P((const char *, ...));


__PTL_END_DECLS

#endif /* __PTL_PTHREAD_H__ */
