1 /* $OpenBSD: rf_threadstuff.h,v 1.8 2002/12/16 07:01:05 tdeval Exp $ */ 2 /* $NetBSD: rf_threadstuff.h,v 1.8 2000/06/11 03:35:38 oster Exp $ */ 3 4 /* 5 * Copyright (c) 1995 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Mark Holland, Daniel Stodolsky, Jim Zelenka 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31 /* 32 * threadstuff.h -- Definitions for threads, locks, and synchronization. 33 * 34 * The purpose of this file is provide some illusion of portability. 35 * If the functions below can be implemented with the same semantics on 36 * some new system, then at least the synchronization and thread control 37 * part of the code should not require modification to port to a new machine. 38 * The only other place where the pthread package is explicitly used is 39 * threadid.h 40 * 41 * This file should be included above stdio.h to get some necessary defines. 42 * 43 */ 44 45 #ifndef _RF__RF_THREADSTUFF_H_ 46 #define _RF__RF_THREADSTUFF_H_ 47 48 #include "rf_types.h" 49 #include <sys/types.h> 50 #include <sys/param.h> 51 #ifdef _KERNEL 52 #include <sys/systm.h> 53 #include <sys/proc.h> 54 #include <sys/kthread.h> 55 #endif 56 57 #define rf_create_managed_mutex(a,b) \ 58 _rf_create_managed_mutex(a,b,__FILE__,__LINE__) 59 #define rf_create_managed_cond(a,b) \ 60 _rf_create_managed_cond(a,b,__FILE__,__LINE__) 61 #define rf_init_managed_threadgroup(a,b) \ 62 _rf_init_managed_threadgroup(a,b,__FILE__,__LINE__) 63 #define rf_init_threadgroup(a) \ 64 _rf_init_threadgroup(a,__FILE__,__LINE__) 65 #define rf_destroy_threadgroup(a) \ 66 _rf_destroy_threadgroup(a,__FILE__,__LINE__) 67 68 int _rf_init_threadgroup(RF_ThreadGroup_t *, char *, int); 69 int _rf_destroy_threadgroup(RF_ThreadGroup_t *, char *, int); 70 int _rf_init_managed_threadgroup(RF_ShutdownList_t **, RF_ThreadGroup_t *, 71 char *, int); 72 73 #include <sys/lock.h> 74 #define decl_simple_lock_data(a,b) a struct simplelock b 75 #define simple_lock_addr(a) ((struct simplelock *)&(a)) 76 77 typedef struct proc *RF_Thread_t; 78 typedef void *RF_ThreadArg_t; 79 80 #define RF_DECLARE_MUTEX(_m_) decl_simple_lock_data(,(_m_)) 81 #define RF_DECLARE_STATIC_MUTEX(_m_) decl_simple_lock_data(static,(_m_)) 82 #define RF_DECLARE_EXTERN_MUTEX(_m_) decl_simple_lock_data(extern,(_m_)) 83 84 #define RF_DECLARE_COND(_c_) int _c_ 85 #define RF_DECLARE_STATIC_COND(_c_) static int _c_ 86 #define RF_DECLARE_EXTERN_COND(_c_) extern int _c_ 87 88 #define RF_LOCK_MUTEX(_m_) simple_lock(&(_m_)) 89 #define RF_UNLOCK_MUTEX(_m_) simple_unlock(&(_m_)) 90 91 /* 92 * In Net- and OpenBSD, kernel threads are simply processes that share several 93 * substructures and never run in userspace. 94 */ 95 #define RF_WAIT_COND(_c_,_m_) do { \ 96 RF_UNLOCK_MUTEX(_m_); \ 97 tsleep(&_c_, PRIBIO, "rfwcond", 0); \ 98 RF_LOCK_MUTEX(_m_); \ 99 } while (0) 100 #define RF_SIGNAL_COND(_c_) wakeup(&(_c_)) 101 #define RF_BROADCAST_COND(_c_) wakeup(&(_c_)) 102 #define RF_CREATE_THREAD(_handle_, _func_, _arg_, _name_) \ 103 kthread_create((void (*)(void *))(_func_), (void *)(_arg_), \ 104 (struct proc **)&(_handle_), _name_) 105 106 struct RF_ThreadGroup_s { 107 int created; 108 int running; 109 int shutdown; 110 RF_DECLARE_MUTEX (mutex); 111 RF_DECLARE_COND (cond); 112 }; 113 114 /* 115 * Someone has started a thread in the group. 116 */ 117 #define RF_THREADGROUP_STARTED(_g_) do { \ 118 RF_LOCK_MUTEX((_g_)->mutex); \ 119 (_g_)->created++; \ 120 RF_UNLOCK_MUTEX((_g_)->mutex); \ 121 } while (0) 122 123 /* 124 * Thread announcing that it is now running. 125 */ 126 #define RF_THREADGROUP_RUNNING(_g_) do { \ 127 RF_LOCK_MUTEX((_g_)->mutex); \ 128 (_g_)->running++; \ 129 RF_UNLOCK_MUTEX((_g_)->mutex); \ 130 RF_SIGNAL_COND((_g_)->cond); \ 131 } while (0) 132 133 /* 134 * Thread announcing that it is now done. 135 */ 136 #define RF_THREADGROUP_DONE(_g_) do { \ 137 RF_LOCK_MUTEX((_g_)->mutex); \ 138 (_g_)->shutdown++; \ 139 RF_UNLOCK_MUTEX((_g_)->mutex); \ 140 RF_SIGNAL_COND((_g_)->cond); \ 141 } while (0) 142 143 /* 144 * Wait for all threads to start running. 145 */ 146 #define RF_THREADGROUP_WAIT_START(_g_) do { \ 147 RF_LOCK_MUTEX((_g_)->mutex); \ 148 while((_g_)->running < (_g_)->created) { \ 149 RF_WAIT_COND((_g_)->cond, (_g_)->mutex); \ 150 } \ 151 RF_UNLOCK_MUTEX((_g_)->mutex); \ 152 } while (0) 153 154 /* 155 * Wait for all threads to stop running. 156 */ 157 #if !defined(__NetBSD__) && !defined(__OpenBSD__) 158 #define RF_THREADGROUP_WAIT_STOP(_g_) do { \ 159 RF_LOCK_MUTEX((_g_)->mutex); \ 160 RF_ASSERT((_g_)->running == (_g_)->created); \ 161 while((_g_)->shutdown < (_g_)->running) { \ 162 RF_WAIT_COND((_g_)->cond, (_g_)->mutex); \ 163 } \ 164 RF_UNLOCK_MUTEX((_g_)->mutex); \ 165 } while (0) 166 #else 167 /* 168 * XXX Note that we've removed the assert. That should be put back in once 169 * we actually get something like a kernel thread running. 170 */ 171 #define RF_THREADGROUP_WAIT_STOP(_g_) do { \ 172 RF_LOCK_MUTEX((_g_)->mutex); \ 173 while((_g_)->shutdown < (_g_)->running) { \ 174 RF_WAIT_COND((_g_)->cond, (_g_)->mutex); \ 175 } \ 176 RF_UNLOCK_MUTEX((_g_)->mutex); \ 177 } while (0) 178 #endif 179 180 181 int rf_mutex_init(struct simplelock *); 182 int rf_mutex_destroy(struct simplelock *); 183 int _rf_create_managed_mutex(RF_ShutdownList_t **, struct simplelock *, 184 char *, int); 185 int _rf_create_managed_cond(RF_ShutdownList_t ** listp, int *, char *, int); 186 187 int rf_cond_init(int *); 188 int rf_cond_destroy(int *); 189 190 #endif /* !_RF__RF_THREADSTUFF_H_ */ 191