Home | History | Annotate | Download | only in src
      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