1241675Suqs/* 2241675Suqs * CDDL HEADER START 3241675Suqs * 4241675Suqs * The contents of this file are subject to the terms of the 5241675Suqs * Common Development and Distribution License (the "License"). 6241675Suqs * You may not use this file except in compliance with the License. 7241675Suqs * 8241675Suqs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9241675Suqs * or http://www.opensolaris.org/os/licensing. 10241675Suqs * See the License for the specific language governing permissions 11241675Suqs * and limitations under the License. 12241675Suqs * 13241675Suqs * When distributing Covered Code, include this CDDL HEADER in each 14241675Suqs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15241675Suqs * If applicable, add the following below this CDDL HEADER, with the 16241675Suqs * fields enclosed by brackets "[]" replaced with your own identifying 17241675Suqs * information: Portions Copyright [yyyy] [name of copyright owner] 18241675Suqs * 19241675Suqs * CDDL HEADER END 20241675Suqs */ 21241675Suqs 22241675Suqs/* 23241675Suqs * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 24241675Suqs */ 25241675Suqs 26241675Suqs#ifndef _SYNCH_H 27241675Suqs#define _SYNCH_H 28241675Suqs 29241675Suqs/* 30241675Suqs * synch.h: 31241675Suqs * definitions needed to use the thread synchronization interface 32241675Suqs */ 33241675Suqs 34241675Suqs#ifndef _ASM 35241675Suqs#include <sys/machlock.h> 36241675Suqs#include <sys/time_impl.h> 37241675Suqs#include <sys/synch.h> 38241675Suqs#endif /* _ASM */ 39241675Suqs 40241675Suqs#ifdef __cplusplus 41241675Suqsextern "C" { 42241675Suqs#endif 43241675Suqs 44241675Suqs#ifndef _ASM 45241675Suqs 46241675Suqs/* 47241675Suqs * Semaphores 48241675Suqs */ 49241675Suqstypedef struct _sema { 50241675Suqs /* this structure must be the same as sem_t in <semaphore.h> */ 51241675Suqs uint32_t count; /* semaphore count */ 52241675Suqs uint16_t type; 53241675Suqs uint16_t magic; 54241675Suqs upad64_t pad1[3]; /* reserved for a mutex_t */ 55241675Suqs upad64_t pad2[2]; /* reserved for a cond_t */ 56241675Suqs} sema_t; 57241675Suqs 58241675Suqs/* 59241675Suqs * POSIX.1c Note: 60241675Suqs * POSIX.1c requires that <pthread.h> define the structures pthread_mutex_t 61241675Suqs * and pthread_cond_t. These structures are identical to mutex_t (lwp_mutex_t) 62241675Suqs * and cond_t (lwp_cond_t) which are defined in <synch.h>. A nested included 63241675Suqs * of <synch.h> (to allow a "#typedef mutex_t pthread_mutex_t") would pull in 64241675Suqs * non-posix symbols/constants violating the namespace restrictions. Hence, 65241675Suqs * pthread_mutex_t/pthread_cond_t have been redefined in <pthread.h> (actually 66241675Suqs * in <sys/types.h>). Any modifications done to mutex_t/lwp_mutex_t or 67241675Suqs * cond_t/lwp_cond_t should also be done to pthread_mutex_t/pthread_cond_t. 68241675Suqs */ 69241675Suqstypedef lwp_mutex_t mutex_t; 70241675Suqstypedef lwp_cond_t cond_t; 71241675Suqs 72241675Suqs/* 73241675Suqs * Readers/writer locks 74241675Suqs * 75241675Suqs * NOTE: The layout of this structure should be kept in sync with the layout 76241675Suqs * of the correponding structure of pthread_rwlock_t in sys/types.h. 77241675Suqs * Also, there is an identical structure for lwp_rwlock_t in <sys/synch.h>. 78241675Suqs * Because we have to deal with C++, we cannot redefine this one as that one. 79241675Suqs */ 80241675Suqstypedef struct _rwlock { 81241675Suqs int32_t readers; /* rwstate word */ 82241675Suqs uint16_t type; 83241675Suqs uint16_t magic; 84241675Suqs mutex_t mutex; /* used with process-shared rwlocks */ 85241675Suqs cond_t readercv; /* used only to indicate ownership */ 86241675Suqs cond_t writercv; /* used only to indicate ownership */ 87241675Suqs} rwlock_t; 88241675Suqs 89241675Suqs#ifdef __STDC__ 90241675Suqsint _lwp_mutex_lock(lwp_mutex_t *); 91241675Suqsint _lwp_mutex_unlock(lwp_mutex_t *); 92241675Suqsint _lwp_mutex_trylock(lwp_mutex_t *); 93241675Suqsint _lwp_cond_wait(lwp_cond_t *, lwp_mutex_t *); 94241675Suqsint _lwp_cond_timedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *); 95241675Suqsint _lwp_cond_reltimedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *); 96241675Suqsint _lwp_cond_signal(lwp_cond_t *); 97241675Suqsint _lwp_cond_broadcast(lwp_cond_t *); 98241675Suqsint _lwp_sema_init(lwp_sema_t *, int); 99241675Suqsint _lwp_sema_wait(lwp_sema_t *); 100241675Suqsint _lwp_sema_trywait(lwp_sema_t *); 101241675Suqsint _lwp_sema_post(lwp_sema_t *); 102241675Suqsint cond_init(cond_t *, int, void *); 103241675Suqsint cond_destroy(cond_t *); 104241675Suqsint cond_wait(cond_t *, mutex_t *); 105241675Suqsint cond_timedwait(cond_t *, mutex_t *, const timespec_t *); 106241675Suqsint cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *); 107241675Suqsint cond_signal(cond_t *); 108241675Suqsint cond_broadcast(cond_t *); 109241675Suqsint mutex_init(mutex_t *, int, void *); 110241675Suqsint mutex_destroy(mutex_t *); 111241675Suqsint mutex_consistent(mutex_t *); 112241675Suqsint mutex_lock(mutex_t *); 113241675Suqsint mutex_trylock(mutex_t *); 114241675Suqsint mutex_unlock(mutex_t *); 115241675Suqsint rwlock_init(rwlock_t *, int, void *); 116241675Suqsint rwlock_destroy(rwlock_t *); 117241675Suqsint rw_rdlock(rwlock_t *); 118241675Suqsint rw_wrlock(rwlock_t *); 119241675Suqsint rw_unlock(rwlock_t *); 120241675Suqsint rw_tryrdlock(rwlock_t *); 121241675Suqsint rw_trywrlock(rwlock_t *); 122241675Suqsint sema_init(sema_t *, unsigned int, int, void *); 123241675Suqsint sema_destroy(sema_t *); 124241675Suqsint sema_wait(sema_t *); 125241675Suqsint sema_timedwait(sema_t *, const timespec_t *); 126241675Suqsint sema_reltimedwait(sema_t *, const timespec_t *); 127241675Suqsint sema_post(sema_t *); 128241675Suqsint sema_trywait(sema_t *); 129241675Suqs 130241675Suqs#else /* __STDC__ */ 131241675Suqs 132241675Suqsint _lwp_mutex_lock(); 133241675Suqsint _lwp_mutex_unlock(); 134241675Suqsint _lwp_mutex_trylock(); 135241675Suqsint _lwp_cond_wait(); 136241675Suqsint _lwp_cond_timedwait(); 137241675Suqsint _lwp_cond_reltimedwait(); 138241675Suqsint _lwp_cond_signal(); 139241675Suqsint _lwp_cond_broadcast(); 140241675Suqsint _lwp_sema_init(); 141241675Suqsint _lwp_sema_wait(); 142241675Suqsint _lwp_sema_trywait(); 143241675Suqsint _lwp_sema_post(); 144241675Suqsint cond_init(); 145241675Suqsint cond_destroy(); 146241675Suqsint cond_wait(); 147241675Suqsint cond_timedwait(); 148241675Suqsint cond_reltimedwait(); 149241675Suqsint cond_signal(); 150241675Suqsint cond_broadcast(); 151241675Suqsint mutex_init(); 152241675Suqsint mutex_destroy(); 153241675Suqsint mutex_consistent(); 154241675Suqsint mutex_lock(); 155241675Suqsint mutex_trylock(); 156241675Suqsint mutex_unlock(); 157241675Suqsint rwlock_init(); 158241675Suqsint rwlock_destroy(); 159241675Suqsint rw_rdlock(); 160241675Suqsint rw_wrlock(); 161241675Suqsint rw_unlock(); 162241675Suqsint rw_tryrdlock(); 163241675Suqsint rw_trywrlock(); 164241675Suqsint sema_init(); 165241675Suqsint sema_destroy(); 166241675Suqsint sema_wait(); 167241675Suqsint sema_timedwait(); 168241675Suqsint sema_reltimedwait(); 169241675Suqsint sema_post(); 170241675Suqsint sema_trywait(); 171241675Suqs 172241675Suqs#endif /* __STDC__ */ 173241675Suqs 174241675Suqs#endif /* _ASM */ 175241675Suqs 176241675Suqs/* "Magic numbers" tagging synchronization object types */ 177241675Suqs#define MUTEX_MAGIC _MUTEX_MAGIC 178241675Suqs#define SEMA_MAGIC _SEMA_MAGIC 179241675Suqs#define COND_MAGIC _COND_MAGIC 180241675Suqs#define RWL_MAGIC _RWL_MAGIC 181241675Suqs 182241675Suqs/* 183241675Suqs * POSIX.1c Note: 184241675Suqs * DEFAULTMUTEX is defined same as PTHREAD_MUTEX_INITIALIZER in <pthread.h>. 185241675Suqs * DEFAULTCV is defined same as PTHREAD_COND_INITIALIZER in <pthread.h>. 186241675Suqs * DEFAULTRWLOCK is defined same as PTHREAD_RWLOCK_INITIALIZER in <pthread.h>. 187241675Suqs * Any changes to these macros should be reflected in <pthread.h> 188241675Suqs */ 189241675Suqs#define DEFAULTMUTEX \ 190241675Suqs {{0, 0, 0, {USYNC_THREAD}, MUTEX_MAGIC}, \ 191241675Suqs {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 192241675Suqs#define SHAREDMUTEX \ 193241675Suqs {{0, 0, 0, {USYNC_PROCESS}, MUTEX_MAGIC}, \ 194241675Suqs {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 195241675Suqs#define RECURSIVEMUTEX \ 196241675Suqs {{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE}, MUTEX_MAGIC}, \ 197241675Suqs {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 198241675Suqs#define ERRORCHECKMUTEX \ 199241675Suqs {{0, 0, 0, {USYNC_THREAD|LOCK_ERRORCHECK}, MUTEX_MAGIC}, \ 200241675Suqs {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 201241675Suqs#define RECURSIVE_ERRORCHECKMUTEX \ 202241675Suqs {{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE|LOCK_ERRORCHECK}, \ 203241675Suqs MUTEX_MAGIC}, {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 204241675Suqs#define DEFAULTCV \ 205241675Suqs {{{0, 0, 0, 0}, USYNC_THREAD, COND_MAGIC}, 0} 206241675Suqs#define SHAREDCV \ 207241675Suqs {{{0, 0, 0, 0}, USYNC_PROCESS, COND_MAGIC}, 0} 208241675Suqs#define DEFAULTSEMA \ 209241675Suqs {0, USYNC_THREAD, SEMA_MAGIC, {0, 0, 0}, {0, 0}} 210241675Suqs#define SHAREDSEMA \ 211241675Suqs {0, USYNC_PROCESS, SEMA_MAGIC, {0, 0, 0}, {0, 0}} 212241675Suqs#define DEFAULTRWLOCK \ 213241675Suqs {0, USYNC_THREAD, RWL_MAGIC, DEFAULTMUTEX, DEFAULTCV, DEFAULTCV} 214241675Suqs#define SHAREDRWLOCK \ 215241675Suqs {0, USYNC_PROCESS, RWL_MAGIC, SHAREDMUTEX, SHAREDCV, SHAREDCV} 216241675Suqs 217241675Suqs/* 218241675Suqs * Tests on lock states. 219241675Suqs */ 220241675Suqs#define SEMA_HELD(x) _sema_held(x) 221241675Suqs#define RW_READ_HELD(x) _rw_read_held(x) 222241675Suqs#define RW_WRITE_HELD(x) _rw_write_held(x) 223241675Suqs#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x)) 224241675Suqs#define MUTEX_HELD(x) _mutex_held(x) 225241675Suqs 226241675Suqs/* 227241675Suqs * The following definitions are for assertions which can be checked 228241675Suqs * statically by tools like lock_lint. You can also define your own 229241675Suqs * run-time test for each. If you don't, we define them to 1 so that 230241675Suqs * such assertions simply pass. 231241675Suqs */ 232241675Suqs#ifndef NO_LOCKS_HELD 233241675Suqs#define NO_LOCKS_HELD 1 234241675Suqs#endif 235241675Suqs#ifndef NO_COMPETING_THREADS 236241675Suqs#define NO_COMPETING_THREADS 1 237241675Suqs#endif 238241675Suqs 239241675Suqs#ifndef _ASM 240241675Suqs 241241675Suqs#ifdef __STDC__ 242241675Suqs 243241675Suqs/* 244241675Suqs * The *_held() functions apply equally well to Solaris threads 245241675Suqs * and to Posix threads synchronization objects, but the formal 246241675Suqs * type declarations are different, so we just declare the argument 247241675Suqs * to each *_held() function to be a void *, expecting that they will 248241675Suqs * be called with the proper type of argument in each case. 249241675Suqs */ 250241675Suqsint _sema_held(void *); /* sema_t or sem_t */ 251241675Suqsint _rw_read_held(void *); /* rwlock_t or pthread_rwlock_t */ 252241675Suqsint _rw_write_held(void *); /* rwlock_t or pthread_rwlock_t */ 253241675Suqsint _mutex_held(void *); /* mutex_t or pthread_mutex_t */ 254241675Suqs 255241675Suqs#else /* __STDC__ */ 256241675Suqs 257241675Suqsint _sema_held(); 258241675Suqsint _rw_read_held(); 259241675Suqsint _rw_write_held(); 260241675Suqsint _mutex_held(); 261241675Suqs 262241675Suqs#endif /* __STDC__ */ 263241675Suqs 264241675Suqs/* Pause API */ 265241675Suqs#ifdef __STDC__ 266241675Suqsvoid smt_pause(void); 267241675Suqs#else /* __STDC__ */ 268241675Suqsvoid smt_pause(); 269241675Suqs#endif /* __STDC__ */ 270241675Suqs 271241675Suqs#endif /* _ASM */ 272241675Suqs 273241675Suqs#ifdef __cplusplus 274241675Suqs} 275241675Suqs#endif 276241675Suqs 277241675Suqs#endif /* _SYNCH_H */ 278241675Suqs