00001 /* $Id: lock.h 31241 2008-03-15 21:26:08Z adam $ */ 00002 /*****************************************************************************/ 00012 /*****************************************************************************/ 00013 00014 /* (c) 2003 Technische Universitaet Dresden 00015 * This file is part of DROPS, which is distributed under the terms of the 00016 * GNU General Public License 2. Please see the COPYING file for details. 00017 */ 00018 00019 #ifndef _L4_LOCK_LOCK_H 00020 #define _L4_LOCK_LOCK_H 00021 00022 /* L4 includes */ 00023 #include <l4/env/cdefs.h> 00024 #include <l4/semaphore/semaphore.h> 00025 00026 /* Lib includes */ 00027 #include <l4/lock/types.h> 00028 00029 /***************************************************************************** 00030 *** prototypes 00031 *****************************************************************************/ 00032 00033 __BEGIN_DECLS; 00034 00035 /*****************************************************************************/ 00044 /*****************************************************************************/ 00045 L4_INLINE void 00046 l4lock_lock(l4lock_t * lock); 00047 00048 /*****************************************************************************/ 00058 /*****************************************************************************/ 00059 L4_INLINE int 00060 l4lock_try_lock(l4lock_t * lock); 00061 00062 /*****************************************************************************/ 00069 /*****************************************************************************/ 00070 L4_INLINE void 00071 l4lock_unlock(l4lock_t * lock); 00072 00073 /*****************************************************************************/ 00082 /*****************************************************************************/ 00083 L4_INLINE l4thread_t 00084 l4lock_owner(const l4lock_t * lock); 00085 00086 __END_DECLS; 00087 00088 /***************************************************************************** 00089 *** implementation 00090 *****************************************************************************/ 00091 00092 /***************************************************************************** 00093 * lock 00094 *****************************************************************************/ 00095 L4_INLINE void 00096 l4lock_lock(l4lock_t * lock) 00097 { 00098 l4thread_t me = l4thread_myself(); 00099 00100 /* sanity check */ 00101 if (lock == NULL) 00102 return; 00103 00104 /* reenter? */ 00105 if (l4thread_equal(me,lock->owner)) 00106 { 00107 lock->ref_count++; 00108 return; 00109 } 00110 00111 /* get semaphore */ 00112 l4semaphore_down(&lock->sem); 00113 00114 /* set owner / reference counter */ 00115 lock->owner = me; 00116 lock->ref_count = 1; 00117 } 00118 00119 /***************************************************************************** 00120 * try lock 00121 *****************************************************************************/ 00122 L4_INLINE int 00123 l4lock_try_lock(l4lock_t * lock) 00124 { 00125 l4thread_t me = l4thread_myself(); 00126 00127 /* sanity check */ 00128 if (lock == NULL) 00129 return 0; 00130 00131 /* reenter? */ 00132 if (l4thread_equal(me,lock->owner)) 00133 { 00134 lock->ref_count++; 00135 return 1; 00136 } 00137 00138 /* try to get semaphore */ 00139 if (l4semaphore_try_down(&lock->sem)) 00140 { 00141 /* got semaphore */ 00142 lock->owner = me; 00143 lock->ref_count = 1; 00144 00145 return 1; 00146 } 00147 else 00148 /* semaphore already locked */ 00149 return 0; 00150 } 00151 00152 /***************************************************************************** 00153 * unlock 00154 *****************************************************************************/ 00155 L4_INLINE void 00156 l4lock_unlock(l4lock_t * lock) 00157 { 00158 l4thread_t me = l4thread_myself(); 00159 00160 /* sanity checks */ 00161 if (lock == NULL) 00162 return; 00163 00164 if (!l4thread_equal(lock->owner,me)) 00165 return; 00166 00167 /* decrement reference counter */ 00168 lock->ref_count--; 00169 if (lock->ref_count <= 0) 00170 { 00171 /* release lock */ 00172 lock->owner = L4THREAD_INVALID_ID; 00173 l4semaphore_up(&lock->sem); 00174 } 00175 } 00176 00177 /***************************************************************************** 00178 * owner 00179 *****************************************************************************/ 00180 L4_INLINE l4thread_t 00181 l4lock_owner(const l4lock_t * lock) 00182 { 00183 /* sanity checks */ 00184 if (lock == NULL) 00185 return L4THREAD_INVALID_ID; 00186 00187 /* return owner */ 00188 return lock->owner; 00189 } 00190 00191 #endif /* _L4_LOCK_LOCK_H */