usermode/library/mtm/include/txlock.h

00001 /*
00002     Copyright (C) 2011 Computer Sciences Department, 
00003     University of Wisconsin -- Madison
00004 
00005     ----------------------------------------------------------------------
00006 
00007     This file is part of Mnemosyne: Lightweight Persistent Memory, 
00008     originally developed at the University of Wisconsin -- Madison.
00009 
00010     Mnemosyne was originally developed primarily by Haris Volos
00011     with contributions from Andres Jaan Tack.
00012 
00013     ----------------------------------------------------------------------
00014 
00015     Mnemosyne is free software; you can redistribute it and/or
00016     modify it under the terms of the GNU General Public License
00017     as published by the Free Software Foundation, version 2
00018     of the License.
00019  
00020     Mnemosyne is distributed in the hope that it will be useful,
00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023     GNU General Public License for more details.
00024 
00025     You should have received a copy of the GNU General Public License
00026     along with this program; if not, write to the Free Software
00027     Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00028     Boston, MA  02110-1301, USA.
00029 
00030 ### END HEADER ###
00031 */
00032 
00033 #ifndef _M_TXLOCK_H_GHA983
00034 #define _M_TXLOCK_H_GHA983
00035 
00036 #undef pthread_mutex_t
00037 #undef pthread_mutex_init
00038 #undef pthread_mutex_destroy
00039 #undef pthread_mutex_lock
00040 #undef pthread_mutex_unlock
00041 
00042 #undef pthread_rwlock_t
00043 #undef pthread_rwlock_init
00044 #undef pthread_rwlock_destroy
00045 #undef pthread_rwlock_rdlock
00046 #undef pthread_rwlock_wrlock
00047 #undef pthread_rwlock_unlock
00048 
00049 
00050 //FIXME: These locks are not deadlock safe -- need to 
00051 //drop locks if can't get a lock to avoid deadlock
00052 //See Volos Transact 08
00053 
00054 #include <itm.h>
00055 #include <pthread.h>
00056 
00057 #define DEBUG_PRINTF(format, ...)
00058 //#define DEBUG_PRINTF(format, a, b) printf(format, a, b)
00059 
00060 /* MUTEX TXSAFE LOCKS */
00061 
00062 typedef pthread_mutex_t m_txmutex_t;
00063 
00064 void _ITM_CALL_CONVENTION m_txmutex_unlock_commit_action(void *arg);
00065 
00066 
00067 __attribute__((tm_pure))
00068 static inline 
00069 int m_txmutex_init(m_txmutex_t *txmutex)
00070 {
00071         pthread_mutex_t *mutex = (pthread_mutex_t *) txmutex;
00072         pthread_mutexattr_t attr;
00073         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00074 
00075         return pthread_mutex_init(mutex, &attr);
00076 }
00077 
00078 
00079 __attribute__((tm_pure))
00080 static inline 
00081 int m_txmutex_destroy(m_txmutex_t *txmutex)
00082 {
00083         pthread_mutex_t *mutex = (pthread_mutex_t *) txmutex;
00084 
00085         return pthread_mutex_destroy(mutex);
00086 }
00087 
00088 __attribute__((noinline))
00089 static
00090 void breakme() { }
00091 
00092 __attribute__((tm_pure))
00093 static inline 
00094 int m_txmutex_lock(m_txmutex_t *txmutex)
00095 {
00096         pthread_mutex_t *mutex = (pthread_mutex_t *) txmutex;
00097         int ret;
00098 
00099         DEBUG_PRINTF("[%d] NOW  : MUTEX  LOCK   %p\n", pthread_self(), mutex);
00100         ret = pthread_mutex_lock(mutex);
00101         DEBUG_PRINTF("[%d] NOW  : MUTEX  LOCK   %p DONE\n", pthread_self(), mutex);
00102 
00103         return ret;
00104 }
00105 
00106 
00107 void _ITM_CALL_CONVENTION m_txmutex_unlock_commit_action_local(void *arg)
00108 {
00109         m_txmutex_t *txmutex = (m_txmutex_t *) arg;
00110         pthread_mutex_t *mutex = (pthread_mutex_t *) txmutex;
00111 
00112         //printf("[%d] COMMIT: MUTEX  UNLOCK %p\n", pthread_self(), mutex);
00113         pthread_mutex_unlock(mutex);
00114 
00115         return;
00116 }
00117 
00118 
00119 
00120 __attribute__((tm_pure))
00121 static inline 
00122 int m_txmutex_unlock(m_txmutex_t *txmutex)
00123 {
00124         int             ret;
00125         pthread_mutex_t *mutex = (pthread_mutex_t *) txmutex;
00126 
00127         _ITM_transaction * td;
00128         td = _ITM_getTransaction();
00129 
00130         if (_ITM_inTransaction(td) > 0) {
00131                 DEBUG_PRINTF("[%d] DEFER: MUTEX  UNLOCK %p\n", pthread_self(), mutex);
00132                 _ITM_addUserCommitAction (td, m_txmutex_unlock_commit_action_local, 2, txmutex);
00133                 //_ITM_addUserCommitAction (td, m_txmutex_unlock_commit_action_local, 2, txmutex);
00134                 ret = 0;
00135         } else {
00136                 DEBUG_PRINTF("[%d] NOW  : MUTEX  UNLOCK %p\n", pthread_self(), mutex);
00137                 ret = pthread_mutex_unlock (mutex);
00138         }
00139 
00140         return ret;
00141 }
00142 
00143 /* READER/WRITER TXSAFE LOCKS */
00144 
00145 typedef pthread_rwlock_t m_txrwlock_t;
00146 
00147 void _ITM_CALL_CONVENTION m_txrwlock_unlock_commit_action(void *arg);
00148 
00149 
00150 __attribute__((tm_pure))
00151 static inline 
00152 int m_txrwlock_init(m_txrwlock_t *txrwlock)
00153 {
00154         pthread_rwlock_t *rwlock = (pthread_rwlock_t *) txrwlock;
00155 
00156         return pthread_rwlock_init(rwlock, NULL);
00157 }
00158 
00159 
00160 __attribute__((tm_pure))
00161 static inline 
00162 int m_txrwlock_destroy(m_txrwlock_t *txrwlock)
00163 {
00164         pthread_rwlock_t *rwlock = (pthread_rwlock_t *) txrwlock;
00165 
00166         return pthread_rwlock_destroy(rwlock);
00167 }
00168 
00169 
00170 __attribute__((tm_pure))
00171 static inline 
00172 int m_txrwlock_rdlock(m_txrwlock_t *txrwlock)
00173 {
00174         pthread_rwlock_t *rwlock = (pthread_rwlock_t *) txrwlock;
00175 
00176         /* 
00177          * TODO: Support a thread re-locking a lock it owns as 
00178          * locks are not released till commit
00179          */
00180         DEBUG_PRINTF("[%d] NOW  : RWLOCK RDLOCK %p\n", pthread_self(), rwlock);
00181         return pthread_rwlock_rdlock(rwlock);
00182 }
00183 
00184 
00185 __attribute__((tm_pure))
00186 static inline 
00187 int m_txrwlock_wrlock(m_txrwlock_t *txrwlock)
00188 {
00189         pthread_rwlock_t *rwlock = (pthread_rwlock_t *) txrwlock;
00190 
00191         /* 
00192          * TODO: Support a thread re-locking a lock it owns as 
00193          * locks are not released till commit
00194          */
00195         DEBUG_PRINTF("[%d] NOW  : RWLOCK WRLOCK %p\n", pthread_self(), rwlock);
00196         return pthread_rwlock_wrlock(rwlock);
00197 }
00198 
00199 
00200 __attribute__((tm_pure))
00201 static inline 
00202 int m_txrwlock_unlock(m_txrwlock_t *txrwlock)
00203 {
00204         int             ret;
00205         pthread_rwlock_t *rwlock = (pthread_rwlock_t *) txrwlock;
00206 
00207         _ITM_transaction * td;
00208         td = _ITM_getTransaction();
00209 
00210         if (_ITM_inTransaction(td) > 0) {
00211                 DEBUG_PRINTF("[%d] DEFER: RWLOCK UNLOCK %p\n", pthread_self(), rwlock);
00212                 _ITM_addUserCommitAction (td, m_txrwlock_unlock_commit_action, 2, txrwlock);
00213                 ret = 0;
00214         } else {
00215                 DEBUG_PRINTF("[%d] NOW  : RWLOCK UNLOCK %p\n", pthread_self(), rwlock);
00216                 ret = pthread_rwlock_unlock (rwlock);
00217         }
00218 
00219         return ret;
00220 }
00221 
00222 
00223 #endif

Generated on Sat Apr 23 11:43:36 2011 for Mnemosyne by  doxygen 1.4.7