00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef LUMIERA_MUTEX_H
00023 #define LUMIERA_MUTEX_H
00024
00025 #include "lib/error.h"
00026
00027 #include <pthread.h>
00028 #include <nobug.h>
00029
00035 LUMIERA_ERROR_DECLARE (MUTEX_LOCK);
00036 LUMIERA_ERROR_DECLARE (MUTEX_UNLOCK);
00037 LUMIERA_ERROR_DECLARE (MUTEX_DESTROY);
00038
00042 #define LUMIERA_MUTEX_SECTION(nobugflag, mtx) \
00043 for (lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ \
00044 = {(LumieraMutex)1 NOBUG_RESOURCE_HANDLE_COMMA_INITIALIZER}; \
00045 lumiera_mutex_section_.mutex;) \
00046 for ( \
00047 ({ \
00048 lumiera_mutex_section_.mutex = (mtx); \
00049 NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \
00050 RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire mutex", &lumiera_mutex_section_, \
00051 NOBUG_RESOURCE_EXCLUSIVE, lumiera_mutex_section_.rh); \
00052 if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \
00053 }); \
00054 lumiera_mutex_section_.mutex; \
00055 ({ \
00056 if (lumiera_mutex_section_.mutex) \
00057 { \
00058 pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \
00059 lumiera_mutex_section_.mutex = NULL; \
00060 RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \
00061 } \
00062 }))
00063
00071 #define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \
00072 for (lumiera_mutexacquirer *lumiera_mutex_section_old_ = &lumiera_mutex_section_, \
00073 NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ = {(LumieraMutex)1 \
00074 NOBUG_RESOURCE_HANDLE_COMMA_INITIALIZER}; \
00075 lumiera_mutex_section_.mutex;) \
00076 for ( \
00077 ({ \
00078 lumiera_mutex_section_.mutex = (mtx); \
00079 NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \
00080 RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire mutex", &lumiera_mutex_section_, \
00081 NOBUG_RESOURCE_EXCLUSIVE, lumiera_mutex_section_.rh); \
00082 if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \
00083 if (lumiera_mutex_section_old_->mutex) \
00084 { \
00085 pthread_mutex_unlock (&lumiera_mutex_section_old_->mutex->mutex); \
00086 lumiera_mutex_section_old_->mutex = NULL; \
00087 RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_old_->rh); \
00088 } \
00089 }); \
00090 lumiera_mutex_section_.mutex; \
00091 ({ \
00092 if (lumiera_mutex_section_.mutex) \
00093 { \
00094 pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \
00095 lumiera_mutex_section_.mutex = NULL; \
00096 RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \
00097 } \
00098 }))
00099
00100
00104 #define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \
00105 for (lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ = {(LumieraMutex)1 \
00106 NOBUG_RESOURCE_HANDLE_COMMA_INITIALIZER}; \
00107 lumiera_mutex_section_.mutex;) \
00108 for ( \
00109 ({ \
00110 lumiera_mutex_section_.mutex = (mtx); \
00111 NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \
00112 RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", &lumiera_mutex_section_, \
00113 NOBUG_RESOURCE_RECURSIVE, lumiera_mutex_section_.rh); \
00114 if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \
00115 }); \
00116 lumiera_mutex_section_.mutex; \
00117 ({ \
00118 if (lumiera_mutex_section_.mutex) \
00119 { \
00120 pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \
00121 lumiera_mutex_section_.mutex = NULL; \
00122 RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \
00123 } \
00124 }))
00125
00126
00134 #define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \
00135 for (lumiera_mutexacquirer *lumiera_mutex_section_old_ = &lumiera_mutex_section_, \
00136 NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ = {(LumieraMutex)1 \
00137 NOBUG_RESOURCE_HANDLE_COMMA_INITIALIZER}; \
00138 lumiera_mutex_section_.mutex;) \
00139 for ( \
00140 ({ \
00141 lumiera_mutex_section_.mutex = (mtx); \
00142 NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \
00143 RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", &lumiera_mutex_section_, \
00144 NOBUG_RESOURCE_RECURSIVE, lumiera_mutex_section_.rh); \
00145 if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \
00146 if (lumiera_mutex_section_old_->mutex) \
00147 { \
00148 pthread_mutex_unlock (&lumiera_mutex_section_old_->mutex->mutex); \
00149 lumiera_mutex_section_old_->mutex = NULL; \
00150 RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_old_->rh); \
00151 } \
00152 }); \
00153 lumiera_mutex_section_.mutex; \
00154 ({ \
00155 if (lumiera_mutex_section_.mutex) \
00156 { \
00157 pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \
00158 lumiera_mutex_section_.mutex = NULL; \
00159 RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \
00160 } \
00161 }))
00162
00163
00168 struct lumiera_mutex_struct
00169 {
00170 pthread_mutex_t mutex;
00171 RESOURCE_HANDLE (rh);
00172 };
00173 typedef struct lumiera_mutex_struct lumiera_mutex;
00174 typedef lumiera_mutex* LumieraMutex;
00175
00176
00183 LumieraMutex
00184 lumiera_mutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* flag);
00185
00192 LumieraMutex
00193 lumiera_recmutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* flag);
00194
00195
00201 LumieraMutex
00202 lumiera_mutex_destroy (LumieraMutex self, struct nobug_flag* flag);
00203
00204
00208 struct lumiera_mutexacquirer_struct
00209 {
00210 LumieraMutex mutex;
00211 RESOURCE_HANDLE (rh);
00212 };
00213 typedef struct lumiera_mutexacquirer_struct lumiera_mutexacquirer;
00214 typedef struct lumiera_mutexacquirer_struct* LumieraMutexacquirer;
00215
00216
00217 static inline void
00218 lumiera_mutexacquirer_ensureunlocked (LumieraMutexacquirer self)
00219 {
00220 ENSURE (!self->mutex, "forgot to unlock mutex");
00221 }
00222
00223 #endif
00224
00225
00226
00227
00228
00229
00230