1 /************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA 4 * All Rights Reserved. 5 * Copyright 2009 VMware, Inc., Palo Alto, CA., USA 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sub license, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial portions 18 * of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 23 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 25 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 26 * USE OR OTHER DEALINGS IN THE SOFTWARE. 27 * 28 **************************************************************************/ 29 /* 30 * Authors: 31 * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com> 32 */ 33 34 #ifdef HAVE_CONFIG_H 35 #include "config.h" 36 #endif 37 38 #include <stdlib.h> 39 #include <stddef.h> 40 #include <errno.h> 41 #include "wsbm_driver.h" 42 43 struct _WsbmThreadFuncs *wsbmCurThreadFunc = NULL; 44 struct _WsbmVNodeFuncs *wsbmCurVNodeFunc = NULL; 45 46 /* 47 * Single-threaded implementation. 48 */ 49 50 static int 51 n_mutexInit(struct _WsbmMutex *mutex, struct _WsbmThreadFuncs *func) 52 { 53 mutex->func = func; 54 return 0; 55 } 56 57 static int 58 n_condInit(struct _WsbmCond *cond, struct _WsbmThreadFuncs *func) 59 { 60 cond->func = func; 61 return 0; 62 } 63 64 static void 65 n_mutexNone(struct _WsbmMutex *mutex __attribute__ ((unused))) 66 { 67 ; 68 } 69 70 static void 71 n_condNone(struct _WsbmCond *cond __attribute__ ((unused))) 72 { 73 ; 74 } 75 76 static void 77 n_condWait(struct _WsbmCond *cond __attribute__ ((unused)), struct _WsbmMutex *mutex __attribute__ ((unused))) 78 { 79 ; 80 } 81 82 static struct _WsbmThreadFuncs nullFunc = { 83 .mutexInit = n_mutexInit, 84 .mutexFree = n_mutexNone, 85 .mutexLock = n_mutexNone, 86 .mutexUnlock = n_mutexNone, 87 .condInit = n_condInit, 88 .condFree = n_condNone, 89 .condWait = n_condWait, 90 .condBroadcast = n_condNone 91 }; 92 93 struct _WsbmThreadFuncs * 94 wsbmNullThreadFuncs(void) 95 { 96 return &nullFunc; 97 } 98 99 #if (HAVE_PTHREADS == 1) 100 #include "pthread.h" 101 102 /* 103 * pthreads implementation: 104 */ 105 106 struct _WsbmPMutex 107 { 108 struct _WsbmThreadFuncs *func; 109 pthread_mutex_t mutex; 110 }; 111 112 struct _WsbmPCond 113 { 114 struct _WsbmThreadFuncs *func; 115 pthread_cond_t cond; 116 }; 117 118 static inline struct _WsbmPMutex * 119 pMutexConvert(struct _WsbmMutex *m) 120 { 121 union _PMutexConverter 122 { 123 struct _WsbmMutex wm; 124 struct _WsbmPMutex pm; 125 } *um = containerOf(m, union _PMutexConverter, wm); 126 127 return &um->pm; 128 } 129 130 static inline struct _WsbmPCond * 131 pCondConvert(struct _WsbmCond *c) 132 { 133 union _PCondConverter 134 { 135 struct _WsbmCond wc; 136 struct _WsbmPCond pc; 137 } *uc = containerOf(c, union _PCondConverter, wc); 138 139 return &uc->pc; 140 } 141 142 static int 143 p_mutexInit(struct _WsbmMutex *mutex, struct _WsbmThreadFuncs *func) 144 { 145 struct _WsbmPMutex *pMutex = pMutexConvert(mutex); 146 147 if (sizeof(struct _WsbmMutex) < sizeof(struct _WsbmPMutex)) 148 return -EINVAL; 149 150 pMutex->func = func; 151 pthread_mutex_init(&pMutex->mutex, NULL); 152 return 0; 153 } 154 155 static void 156 p_mutexFree(struct _WsbmMutex *mutex) 157 { 158 struct _WsbmPMutex *pMutex = pMutexConvert(mutex); 159 160 pthread_mutex_destroy(&pMutex->mutex); 161 } 162 163 static void 164 p_mutexLock(struct _WsbmMutex *mutex) 165 { 166 struct _WsbmPMutex *pMutex = pMutexConvert(mutex); 167 168 pthread_mutex_lock(&pMutex->mutex); 169 } 170 171 static void 172 p_mutexUnlock(struct _WsbmMutex *mutex) 173 { 174 struct _WsbmPMutex *pMutex = pMutexConvert(mutex); 175 176 pthread_mutex_unlock(&pMutex->mutex); 177 } 178 179 static int 180 p_condInit(struct _WsbmCond *cond, struct _WsbmThreadFuncs *func) 181 { 182 struct _WsbmPCond *pCond = pCondConvert(cond); 183 184 if (sizeof(struct _WsbmCond) < sizeof(struct _WsbmPCond)) 185 return -EINVAL; 186 187 pCond->func = func; 188 pthread_cond_init(&pCond->cond, NULL); 189 return 0; 190 } 191 192 static void 193 p_condFree(struct _WsbmCond *cond) 194 { 195 struct _WsbmPCond *pCond = pCondConvert(cond); 196 197 pthread_cond_destroy(&pCond->cond); 198 } 199 200 static void 201 p_condBroadcast(struct _WsbmCond *cond) 202 { 203 struct _WsbmPCond *pCond = pCondConvert(cond); 204 205 pthread_cond_broadcast(&pCond->cond); 206 } 207 208 static void 209 p_condWait(struct _WsbmCond *cond, struct _WsbmMutex *mutex) 210 { 211 struct _WsbmPCond *pCond = pCondConvert(cond); 212 struct _WsbmPMutex *pMutex = pMutexConvert(mutex); 213 214 pthread_cond_wait(&pCond->cond, &pMutex->mutex); 215 } 216 217 static struct _WsbmThreadFuncs pthreadFunc = { 218 .mutexInit = p_mutexInit, 219 .mutexFree = p_mutexFree, 220 .mutexLock = p_mutexLock, 221 .mutexUnlock = p_mutexUnlock, 222 .condInit = p_condInit, 223 .condFree = p_condFree, 224 .condWait = p_condWait, 225 .condBroadcast = p_condBroadcast 226 }; 227 228 struct _WsbmThreadFuncs * 229 wsbmPThreadFuncs(void) 230 { 231 return &pthreadFunc; 232 } 233 234 #else 235 #warning Pthreads is not present. Compiling without. 236 237 struct _WsbmThreadFuncs * 238 wsbmPThreadFuncs(void) 239 { 240 return &pthreadFunc; 241 } 242 243 #endif 244