17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
541efec2raf * Common Development and Distribution License (the "License").
641efec2raf * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
2141efec2raf
227c478bdstevel@tonic-gate/*
23ba3594bGarrett D'Amore * Copyright 2014 Garrett D'Amore <garrett@damore.org>
24e2c5185Christopher Kiick * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
277c478bdstevel@tonic-gate#ifndef	_SYNCH_H
287c478bdstevel@tonic-gate#define	_SYNCH_H
297c478bdstevel@tonic-gate
307c478bdstevel@tonic-gate/*
317c478bdstevel@tonic-gate * synch.h:
327c478bdstevel@tonic-gate * definitions needed to use the thread synchronization interface
337c478bdstevel@tonic-gate */
347c478bdstevel@tonic-gate
357c478bdstevel@tonic-gate#ifndef _ASM
367c478bdstevel@tonic-gate#include <sys/machlock.h>
377c478bdstevel@tonic-gate#include <sys/time_impl.h>
387c478bdstevel@tonic-gate#include <sys/synch.h>
397c478bdstevel@tonic-gate#endif /* _ASM */
407c478bdstevel@tonic-gate
417c478bdstevel@tonic-gate#ifdef __cplusplus
427c478bdstevel@tonic-gateextern "C" {
437c478bdstevel@tonic-gate#endif
447c478bdstevel@tonic-gate
457c478bdstevel@tonic-gate#ifndef _ASM
467c478bdstevel@tonic-gate
477c478bdstevel@tonic-gate/*
487c478bdstevel@tonic-gate * Semaphores
497c478bdstevel@tonic-gate */
507c478bdstevel@tonic-gatetypedef struct _sema {
517c478bdstevel@tonic-gate	/* this structure must be the same as sem_t in <semaphore.h> */
527c478bdstevel@tonic-gate	uint32_t	count;		/* semaphore count */
537c478bdstevel@tonic-gate	uint16_t	type;
547c478bdstevel@tonic-gate	uint16_t	magic;
557c478bdstevel@tonic-gate	upad64_t	pad1[3];	/* reserved for a mutex_t */
566e270caMarcel Telka	upad64_t	pad2[2];	/* reserved for a cond_t */
577c478bdstevel@tonic-gate} sema_t;
587c478bdstevel@tonic-gate
597c478bdstevel@tonic-gate/*
607c478bdstevel@tonic-gate * POSIX.1c Note:
617c478bdstevel@tonic-gate * POSIX.1c requires that <pthread.h> define the structures pthread_mutex_t
627c478bdstevel@tonic-gate * and pthread_cond_t.  These structures are identical to mutex_t (lwp_mutex_t)
637c478bdstevel@tonic-gate * and cond_t (lwp_cond_t) which are defined in <synch.h>.  A nested included
647c478bdstevel@tonic-gate * of <synch.h> (to allow a "#typedef mutex_t  pthread_mutex_t") would pull in
657c478bdstevel@tonic-gate * non-posix symbols/constants violating the namespace restrictions.  Hence,
667c478bdstevel@tonic-gate * pthread_mutex_t/pthread_cond_t have been redefined in <pthread.h> (actually
677c478bdstevel@tonic-gate * in <sys/types.h>).  Any modifications done to mutex_t/lwp_mutex_t or
687c478bdstevel@tonic-gate * cond_t/lwp_cond_t should also be done to pthread_mutex_t/pthread_cond_t.
697c478bdstevel@tonic-gate */
707c478bdstevel@tonic-gatetypedef lwp_mutex_t mutex_t;
717c478bdstevel@tonic-gatetypedef lwp_cond_t cond_t;
727c478bdstevel@tonic-gate
737c478bdstevel@tonic-gate/*
747c478bdstevel@tonic-gate * Readers/writer locks
757c478bdstevel@tonic-gate *
767c478bdstevel@tonic-gate * NOTE: The layout of this structure should be kept in sync with the layout
777c478bdstevel@tonic-gate * of the correponding structure of pthread_rwlock_t in sys/types.h.
787c478bdstevel@tonic-gate * Also, there is an identical structure for lwp_rwlock_t in <sys/synch.h>.
797c478bdstevel@tonic-gate * Because we have to deal with C++, we cannot redefine this one as that one.
807c478bdstevel@tonic-gate */
817c478bdstevel@tonic-gatetypedef struct _rwlock {
8241efec2raf	int32_t		readers;	/* rwstate word */
837c478bdstevel@tonic-gate	uint16_t	type;
847c478bdstevel@tonic-gate	uint16_t	magic;
8541efec2raf	mutex_t		mutex;		/* used with process-shared rwlocks */
8641efec2raf	cond_t		readercv;	/* used only to indicate ownership */
8741efec2raf	cond_t		writercv;	/* used only to indicate ownership */
887c478bdstevel@tonic-gate} rwlock_t;
897c478bdstevel@tonic-gate
907c478bdstevel@tonic-gateint	_lwp_mutex_lock(lwp_mutex_t *);
917c478bdstevel@tonic-gateint	_lwp_mutex_unlock(lwp_mutex_t *);
927c478bdstevel@tonic-gateint	_lwp_mutex_trylock(lwp_mutex_t *);
937c478bdstevel@tonic-gateint	_lwp_cond_wait(lwp_cond_t *, lwp_mutex_t *);
947c478bdstevel@tonic-gateint	_lwp_cond_timedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *);
957c478bdstevel@tonic-gateint	_lwp_cond_reltimedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *);
967c478bdstevel@tonic-gateint	_lwp_cond_signal(lwp_cond_t *);
977c478bdstevel@tonic-gateint	_lwp_cond_broadcast(lwp_cond_t *);
987c478bdstevel@tonic-gateint	_lwp_sema_init(lwp_sema_t *, int);
997c478bdstevel@tonic-gateint	_lwp_sema_wait(lwp_sema_t *);
1007c478bdstevel@tonic-gateint	_lwp_sema_trywait(lwp_sema_t *);
1017c478bdstevel@tonic-gateint	_lwp_sema_post(lwp_sema_t *);
1027c478bdstevel@tonic-gateint	cond_init(cond_t *, int, void *);
1037c478bdstevel@tonic-gateint	cond_destroy(cond_t *);
1047c478bdstevel@tonic-gateint	cond_wait(cond_t *, mutex_t *);
1057c478bdstevel@tonic-gateint	cond_timedwait(cond_t *, mutex_t *, const timespec_t *);
1067c478bdstevel@tonic-gateint	cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *);
1077c478bdstevel@tonic-gateint	cond_signal(cond_t *);
1087c478bdstevel@tonic-gateint	cond_broadcast(cond_t *);
1097c478bdstevel@tonic-gateint	mutex_init(mutex_t *, int, void *);
1107c478bdstevel@tonic-gateint	mutex_destroy(mutex_t *);
111883492drafint	mutex_consistent(mutex_t *);
1127c478bdstevel@tonic-gateint	mutex_lock(mutex_t *);
1137c478bdstevel@tonic-gateint	mutex_trylock(mutex_t *);
1147c478bdstevel@tonic-gateint	mutex_unlock(mutex_t *);
1157c478bdstevel@tonic-gateint	rwlock_init(rwlock_t *, int, void *);
1167c478bdstevel@tonic-gateint	rwlock_destroy(rwlock_t *);
1177c478bdstevel@tonic-gateint	rw_rdlock(rwlock_t *);
1187c478bdstevel@tonic-gateint	rw_wrlock(rwlock_t *);
1197c478bdstevel@tonic-gateint	rw_unlock(rwlock_t *);
1207c478bdstevel@tonic-gateint	rw_tryrdlock(rwlock_t *);
1217c478bdstevel@tonic-gateint	rw_trywrlock(rwlock_t *);
1227c478bdstevel@tonic-gateint	sema_init(sema_t *, unsigned int, int, void *);
1237c478bdstevel@tonic-gateint	sema_destroy(sema_t *);
1247c478bdstevel@tonic-gateint	sema_wait(sema_t *);
1257c478bdstevel@tonic-gateint	sema_timedwait(sema_t *, const timespec_t *);
1267c478bdstevel@tonic-gateint	sema_reltimedwait(sema_t *, const timespec_t *);
1277c478bdstevel@tonic-gateint	sema_post(sema_t *);
1287c478bdstevel@tonic-gateint	sema_trywait(sema_t *);
1297c478bdstevel@tonic-gate
1307c478bdstevel@tonic-gate#endif /* _ASM */
1317c478bdstevel@tonic-gate
1327c478bdstevel@tonic-gate/* "Magic numbers" tagging synchronization object types */
1337c478bdstevel@tonic-gate#define	MUTEX_MAGIC	_MUTEX_MAGIC
1347c478bdstevel@tonic-gate#define	SEMA_MAGIC	_SEMA_MAGIC
1357c478bdstevel@tonic-gate#define	COND_MAGIC	_COND_MAGIC
1367c478bdstevel@tonic-gate#define	RWL_MAGIC	_RWL_MAGIC
1377c478bdstevel@tonic-gate
1387c478bdstevel@tonic-gate/*
1397c478bdstevel@tonic-gate * POSIX.1c Note:
1407c478bdstevel@tonic-gate * DEFAULTMUTEX is defined same as PTHREAD_MUTEX_INITIALIZER in <pthread.h>.
1417c478bdstevel@tonic-gate * DEFAULTCV is defined same as PTHREAD_COND_INITIALIZER in <pthread.h>.
1427c478bdstevel@tonic-gate * DEFAULTRWLOCK is defined same as PTHREAD_RWLOCK_INITIALIZER in <pthread.h>.
1437c478bdstevel@tonic-gate * Any changes to these macros should be reflected in <pthread.h>
1447c478bdstevel@tonic-gate */
1457c478bdstevel@tonic-gate#define	DEFAULTMUTEX	\
1467c478bdstevel@tonic-gate	{{0, 0, 0, {USYNC_THREAD}, MUTEX_MAGIC}, \
1477c478bdstevel@tonic-gate	{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
1487c478bdstevel@tonic-gate#define	SHAREDMUTEX	\
1497c478bdstevel@tonic-gate	{{0, 0, 0, {USYNC_PROCESS}, MUTEX_MAGIC}, \
1507c478bdstevel@tonic-gate	{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
1517c478bdstevel@tonic-gate#define	RECURSIVEMUTEX	\
1527c478bdstevel@tonic-gate	{{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE}, MUTEX_MAGIC}, \
1537c478bdstevel@tonic-gate	{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
1547c478bdstevel@tonic-gate#define	ERRORCHECKMUTEX	\
1557c478bdstevel@tonic-gate	{{0, 0, 0, {USYNC_THREAD|LOCK_ERRORCHECK}, MUTEX_MAGIC}, \
1567c478bdstevel@tonic-gate	{{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
1577c478bdstevel@tonic-gate#define	RECURSIVE_ERRORCHECKMUTEX	\
1587c478bdstevel@tonic-gate	{{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE|LOCK_ERRORCHECK}, \
1597c478bdstevel@tonic-gate	MUTEX_MAGIC}, {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0}
1607c478bdstevel@tonic-gate#define	DEFAULTCV	\
1617c478bdstevel@tonic-gate	{{{0, 0, 0, 0}, USYNC_THREAD, COND_MAGIC}, 0}
1627c478bdstevel@tonic-gate#define	SHAREDCV	\
1637c478bdstevel@tonic-gate	{{{0, 0, 0, 0}, USYNC_PROCESS, COND_MAGIC}, 0}
1647c478bdstevel@tonic-gate#define	DEFAULTSEMA	\
1657c478bdstevel@tonic-gate	{0, USYNC_THREAD, SEMA_MAGIC, {0, 0, 0}, {0, 0}}
1667c478bdstevel@tonic-gate#define	SHAREDSEMA	\
1677c478bdstevel@tonic-gate	{0, USYNC_PROCESS, SEMA_MAGIC, {0, 0, 0}, {0, 0}}
1687c478bdstevel@tonic-gate#define	DEFAULTRWLOCK	\
1697c478bdstevel@tonic-gate	{0, USYNC_THREAD, RWL_MAGIC, DEFAULTMUTEX, DEFAULTCV, DEFAULTCV}
1707c478bdstevel@tonic-gate#define	SHAREDRWLOCK	\
1717c478bdstevel@tonic-gate	{0, USYNC_PROCESS, RWL_MAGIC, SHAREDMUTEX, SHAREDCV, SHAREDCV}
1727c478bdstevel@tonic-gate
1737c478bdstevel@tonic-gate/*
1747c478bdstevel@tonic-gate * Tests on lock states.
1757c478bdstevel@tonic-gate */
1767c478bdstevel@tonic-gate#define	SEMA_HELD(x)		_sema_held(x)
1777c478bdstevel@tonic-gate#define	RW_READ_HELD(x)		_rw_read_held(x)
1787c478bdstevel@tonic-gate#define	RW_WRITE_HELD(x)	_rw_write_held(x)
1797c478bdstevel@tonic-gate#define	RW_LOCK_HELD(x)		(RW_READ_HELD(x) || RW_WRITE_HELD(x))
1807c478bdstevel@tonic-gate#define	MUTEX_HELD(x)		_mutex_held(x)
1817c478bdstevel@tonic-gate
1827c478bdstevel@tonic-gate/*
1837c478bdstevel@tonic-gate * The following definitions are for assertions which can be checked
1847c478bdstevel@tonic-gate * statically by tools like lock_lint.  You can also define your own
1857c478bdstevel@tonic-gate * run-time test for each.  If you don't, we define them to 1 so that
1867c478bdstevel@tonic-gate * such assertions simply pass.
1877c478bdstevel@tonic-gate */
1887c478bdstevel@tonic-gate#ifndef NO_LOCKS_HELD
1897c478bdstevel@tonic-gate#define	NO_LOCKS_HELD	1
1907c478bdstevel@tonic-gate#endif
1917c478bdstevel@tonic-gate#ifndef NO_COMPETING_THREADS
1927c478bdstevel@tonic-gate#define	NO_COMPETING_THREADS	1
1937c478bdstevel@tonic-gate#endif
1947c478bdstevel@tonic-gate
1957c478bdstevel@tonic-gate#ifndef _ASM
1967c478bdstevel@tonic-gate
19753f3aeaRoger A. Faulkner/*
19853f3aeaRoger A. Faulkner * The *_held() functions apply equally well to Solaris threads
19953f3aeaRoger A. Faulkner * and to Posix threads synchronization objects, but the formal
20053f3aeaRoger A. Faulkner * type declarations are different, so we just declare the argument
20153f3aeaRoger A. Faulkner * to each *_held() function to be a void *, expecting that they will
20253f3aeaRoger A. Faulkner * be called with the proper type of argument in each case.
20353f3aeaRoger A. Faulkner */
20453f3aeaRoger A. Faulknerint _sema_held(void *);			/* sema_t or sem_t */
20553f3aeaRoger A. Faulknerint _rw_read_held(void *);		/* rwlock_t or pthread_rwlock_t */
20653f3aeaRoger A. Faulknerint _rw_write_held(void *);		/* rwlock_t or pthread_rwlock_t */
20753f3aeaRoger A. Faulknerint _mutex_held(void *);		/* mutex_t or pthread_mutex_t */
2087c478bdstevel@tonic-gate
209e2c5185Christopher Kiick/* Pause API */
210e2c5185Christopher Kiickvoid smt_pause(void);
211e2c5185Christopher Kiick
2127c478bdstevel@tonic-gate#endif /* _ASM */
2137c478bdstevel@tonic-gate
2140d045c0Robert Mustacchi/*
2150d045c0Robert Mustacchi * Panicking versions of our favorite friends.
2160d045c0Robert Mustacchi */
2170d045c0Robert Mustacchivoid mutex_enter(mutex_t *);
2180d045c0Robert Mustacchivoid mutex_exit(mutex_t *);
2190d045c0Robert Mustacchi
2207c478bdstevel@tonic-gate#ifdef	__cplusplus
2217c478bdstevel@tonic-gate}
2227c478bdstevel@tonic-gate#endif
2237c478bdstevel@tonic-gate
2247c478bdstevel@tonic-gate#endif	/* _SYNCH_H */
225