1168404Spjd/* 2168404Spjd * CDDL HEADER START 3168404Spjd * 4168404Spjd * The contents of this file are subject to the terms of the 5185029Spjd * Common Development and Distribution License (the "License"). 6185029Spjd * You may not use this file except in compliance with the License. 7168404Spjd * 8168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9168404Spjd * or http://www.opensolaris.org/os/licensing. 10168404Spjd * See the License for the specific language governing permissions 11168404Spjd * and limitations under the License. 12168404Spjd * 13168404Spjd * When distributing Covered Code, include this CDDL HEADER in each 14168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15168404Spjd * If applicable, add the following below this CDDL HEADER, with the 16168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18168404Spjd * 19168404Spjd * CDDL HEADER END 20168404Spjd */ 21185029Spjd 22168404Spjd/* 23270382Sdelphij * Copyright 2014 Garrett D'Amore <garrett@damore.org> 24219089Spjd * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 25168404Spjd */ 26168404Spjd 27168404Spjd#ifndef _SYNCH_H 28168404Spjd#define _SYNCH_H 29168404Spjd 30168404Spjd/* 31168404Spjd * synch.h: 32168404Spjd * definitions needed to use the thread synchronization interface 33168404Spjd */ 34168404Spjd 35168404Spjd#ifndef _ASM 36168404Spjd#include <sys/machlock.h> 37168404Spjd#include <sys/time_impl.h> 38168404Spjd#include <sys/synch.h> 39168404Spjd#endif /* _ASM */ 40168404Spjd 41168404Spjd#ifdef __cplusplus 42168404Spjdextern "C" { 43168404Spjd#endif 44168404Spjd 45168404Spjd#ifndef _ASM 46168404Spjd 47168404Spjd/* 48168404Spjd * Semaphores 49168404Spjd */ 50168404Spjdtypedef struct _sema { 51168404Spjd /* this structure must be the same as sem_t in <semaphore.h> */ 52168404Spjd uint32_t count; /* semaphore count */ 53168404Spjd uint16_t type; 54168404Spjd uint16_t magic; 55168404Spjd upad64_t pad1[3]; /* reserved for a mutex_t */ 56168404Spjd upad64_t pad2[2]; /* reserved for a cond_t */ 57168404Spjd} sema_t; 58168404Spjd 59168404Spjd/* 60168404Spjd * POSIX.1c Note: 61168404Spjd * POSIX.1c requires that <pthread.h> define the structures pthread_mutex_t 62168404Spjd * and pthread_cond_t. These structures are identical to mutex_t (lwp_mutex_t) 63168404Spjd * and cond_t (lwp_cond_t) which are defined in <synch.h>. A nested included 64168404Spjd * of <synch.h> (to allow a "#typedef mutex_t pthread_mutex_t") would pull in 65168404Spjd * non-posix symbols/constants violating the namespace restrictions. Hence, 66168404Spjd * pthread_mutex_t/pthread_cond_t have been redefined in <pthread.h> (actually 67168404Spjd * in <sys/types.h>). Any modifications done to mutex_t/lwp_mutex_t or 68168404Spjd * cond_t/lwp_cond_t should also be done to pthread_mutex_t/pthread_cond_t. 69168404Spjd */ 70168404Spjdtypedef lwp_mutex_t mutex_t; 71168404Spjdtypedef lwp_cond_t cond_t; 72168404Spjd 73168404Spjd/* 74168404Spjd * Readers/writer locks 75168404Spjd * 76168404Spjd * NOTE: The layout of this structure should be kept in sync with the layout 77168404Spjd * of the correponding structure of pthread_rwlock_t in sys/types.h. 78168404Spjd * Also, there is an identical structure for lwp_rwlock_t in <sys/synch.h>. 79168404Spjd * Because we have to deal with C++, we cannot redefine this one as that one. 80168404Spjd */ 81168404Spjdtypedef struct _rwlock { 82185029Spjd int32_t readers; /* rwstate word */ 83168404Spjd uint16_t type; 84168404Spjd uint16_t magic; 85185029Spjd mutex_t mutex; /* used with process-shared rwlocks */ 86185029Spjd cond_t readercv; /* used only to indicate ownership */ 87185029Spjd cond_t writercv; /* used only to indicate ownership */ 88168404Spjd} rwlock_t; 89168404Spjd 90168404Spjdint _lwp_mutex_lock(lwp_mutex_t *); 91168404Spjdint _lwp_mutex_unlock(lwp_mutex_t *); 92168404Spjdint _lwp_mutex_trylock(lwp_mutex_t *); 93168404Spjdint _lwp_cond_wait(lwp_cond_t *, lwp_mutex_t *); 94168404Spjdint _lwp_cond_timedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *); 95168404Spjdint _lwp_cond_reltimedwait(lwp_cond_t *, lwp_mutex_t *, timespec_t *); 96168404Spjdint _lwp_cond_signal(lwp_cond_t *); 97168404Spjdint _lwp_cond_broadcast(lwp_cond_t *); 98168404Spjdint _lwp_sema_init(lwp_sema_t *, int); 99168404Spjdint _lwp_sema_wait(lwp_sema_t *); 100168404Spjdint _lwp_sema_trywait(lwp_sema_t *); 101168404Spjdint _lwp_sema_post(lwp_sema_t *); 102168404Spjdint cond_init(cond_t *, int, void *); 103168404Spjdint cond_destroy(cond_t *); 104168404Spjdint cond_wait(cond_t *, mutex_t *); 105168404Spjdint cond_timedwait(cond_t *, mutex_t *, const timespec_t *); 106168404Spjdint cond_reltimedwait(cond_t *, mutex_t *, const timespec_t *); 107168404Spjdint cond_signal(cond_t *); 108168404Spjdint cond_broadcast(cond_t *); 109168404Spjdint mutex_init(mutex_t *, int, void *); 110168404Spjdint mutex_destroy(mutex_t *); 111185029Spjdint mutex_consistent(mutex_t *); 112168404Spjdint mutex_lock(mutex_t *); 113168404Spjdint mutex_trylock(mutex_t *); 114168404Spjdint mutex_unlock(mutex_t *); 115168404Spjdint rwlock_init(rwlock_t *, int, void *); 116168404Spjdint rwlock_destroy(rwlock_t *); 117168404Spjdint rw_rdlock(rwlock_t *); 118168404Spjdint rw_wrlock(rwlock_t *); 119168404Spjdint rw_unlock(rwlock_t *); 120168404Spjdint rw_tryrdlock(rwlock_t *); 121168404Spjdint rw_trywrlock(rwlock_t *); 122168404Spjdint sema_init(sema_t *, unsigned int, int, void *); 123168404Spjdint sema_destroy(sema_t *); 124168404Spjdint sema_wait(sema_t *); 125168404Spjdint sema_timedwait(sema_t *, const timespec_t *); 126168404Spjdint sema_reltimedwait(sema_t *, const timespec_t *); 127168404Spjdint sema_post(sema_t *); 128168404Spjdint sema_trywait(sema_t *); 129168404Spjd 130168404Spjd#endif /* _ASM */ 131168404Spjd 132168404Spjd/* "Magic numbers" tagging synchronization object types */ 133168404Spjd#define MUTEX_MAGIC _MUTEX_MAGIC 134168404Spjd#define SEMA_MAGIC _SEMA_MAGIC 135168404Spjd#define COND_MAGIC _COND_MAGIC 136168404Spjd#define RWL_MAGIC _RWL_MAGIC 137168404Spjd 138168404Spjd/* 139168404Spjd * POSIX.1c Note: 140168404Spjd * DEFAULTMUTEX is defined same as PTHREAD_MUTEX_INITIALIZER in <pthread.h>. 141168404Spjd * DEFAULTCV is defined same as PTHREAD_COND_INITIALIZER in <pthread.h>. 142168404Spjd * DEFAULTRWLOCK is defined same as PTHREAD_RWLOCK_INITIALIZER in <pthread.h>. 143168404Spjd * Any changes to these macros should be reflected in <pthread.h> 144168404Spjd */ 145168404Spjd#define DEFAULTMUTEX \ 146168404Spjd {{0, 0, 0, {USYNC_THREAD}, MUTEX_MAGIC}, \ 147168404Spjd {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 148168404Spjd#define SHAREDMUTEX \ 149168404Spjd {{0, 0, 0, {USYNC_PROCESS}, MUTEX_MAGIC}, \ 150168404Spjd {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 151168404Spjd#define RECURSIVEMUTEX \ 152168404Spjd {{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE}, MUTEX_MAGIC}, \ 153168404Spjd {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 154168404Spjd#define ERRORCHECKMUTEX \ 155168404Spjd {{0, 0, 0, {USYNC_THREAD|LOCK_ERRORCHECK}, MUTEX_MAGIC}, \ 156168404Spjd {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 157168404Spjd#define RECURSIVE_ERRORCHECKMUTEX \ 158168404Spjd {{0, 0, 0, {USYNC_THREAD|LOCK_RECURSIVE|LOCK_ERRORCHECK}, \ 159168404Spjd MUTEX_MAGIC}, {{{0, 0, 0, 0, 0, 0, 0, 0}}}, 0} 160168404Spjd#define DEFAULTCV \ 161168404Spjd {{{0, 0, 0, 0}, USYNC_THREAD, COND_MAGIC}, 0} 162168404Spjd#define SHAREDCV \ 163168404Spjd {{{0, 0, 0, 0}, USYNC_PROCESS, COND_MAGIC}, 0} 164168404Spjd#define DEFAULTSEMA \ 165168404Spjd {0, USYNC_THREAD, SEMA_MAGIC, {0, 0, 0}, {0, 0}} 166168404Spjd#define SHAREDSEMA \ 167168404Spjd {0, USYNC_PROCESS, SEMA_MAGIC, {0, 0, 0}, {0, 0}} 168168404Spjd#define DEFAULTRWLOCK \ 169168404Spjd {0, USYNC_THREAD, RWL_MAGIC, DEFAULTMUTEX, DEFAULTCV, DEFAULTCV} 170168404Spjd#define SHAREDRWLOCK \ 171168404Spjd {0, USYNC_PROCESS, RWL_MAGIC, SHAREDMUTEX, SHAREDCV, SHAREDCV} 172168404Spjd 173168404Spjd/* 174168404Spjd * Tests on lock states. 175168404Spjd */ 176168404Spjd#define SEMA_HELD(x) _sema_held(x) 177168404Spjd#define RW_READ_HELD(x) _rw_read_held(x) 178168404Spjd#define RW_WRITE_HELD(x) _rw_write_held(x) 179168404Spjd#define RW_LOCK_HELD(x) (RW_READ_HELD(x) || RW_WRITE_HELD(x)) 180168404Spjd#define MUTEX_HELD(x) _mutex_held(x) 181168404Spjd 182168404Spjd/* 183168404Spjd * The following definitions are for assertions which can be checked 184168404Spjd * statically by tools like lock_lint. You can also define your own 185168404Spjd * run-time test for each. If you don't, we define them to 1 so that 186168404Spjd * such assertions simply pass. 187168404Spjd */ 188168404Spjd#ifndef NO_LOCKS_HELD 189168404Spjd#define NO_LOCKS_HELD 1 190168404Spjd#endif 191168404Spjd#ifndef NO_COMPETING_THREADS 192168404Spjd#define NO_COMPETING_THREADS 1 193168404Spjd#endif 194168404Spjd 195168404Spjd#ifndef _ASM 196168404Spjd 197219089Spjd/* 198219089Spjd * The *_held() functions apply equally well to Solaris threads 199219089Spjd * and to Posix threads synchronization objects, but the formal 200219089Spjd * type declarations are different, so we just declare the argument 201219089Spjd * to each *_held() function to be a void *, expecting that they will 202219089Spjd * be called with the proper type of argument in each case. 203219089Spjd */ 204219089Spjdint _sema_held(void *); /* sema_t or sem_t */ 205219089Spjdint _rw_read_held(void *); /* rwlock_t or pthread_rwlock_t */ 206219089Spjdint _rw_write_held(void *); /* rwlock_t or pthread_rwlock_t */ 207219089Spjdint _mutex_held(void *); /* mutex_t or pthread_mutex_t */ 208168404Spjd 209219089Spjd/* Pause API */ 210219089Spjdvoid smt_pause(void); 211219089Spjd 212168404Spjd#endif /* _ASM */ 213168404Spjd 214168404Spjd#ifdef __cplusplus 215168404Spjd} 216168404Spjd#endif 217168404Spjd 218168404Spjd#endif /* _SYNCH_H */ 219