usermode/library/mtm/src/locks.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 /*
00034  * Source code is partially derived from TinySTM (license is attached)
00035  *
00036  *
00037  * Author(s):
00038  *   Pascal Felber <pascal.felber@unine.ch>
00039  *
00040  * Copyright (c) 2007-2009.
00041  *
00042  * This program is free software; you can redistribute it and/or
00043  * modify it under the terms of the GNU General Public License
00044  * as published by the Free Software Foundation, version 2
00045  * of the License.
00046  *
00047  * This program is distributed in the hope that it will be useful,
00048  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00049  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00050  * GNU General Public License for more details.
00051  */
00052 
00053 
00054 #ifndef _LOCKS_H
00055 #define _LOCKS_H
00056 
00057 /* ################################################################### *
00058  * LOCKS
00059  * ################################################################### */
00060 
00061 /*
00062  * A lock is a unsigned int of the size of a pointer.
00063  * The LSB is the lock bit. If it is set, this means:
00064  * - At least some covered memory addresses is being written.
00065  * - Write-back (ETL): all bits of the lock apart from the lock bit form
00066  *   a pointer that points to the write log entry holding the new
00067  *   value. Multiple values covered by the same log entry and orginized
00068  *   in a linked list in the write log.
00069  * - Write-through and write-back (CTL): all bits of the lock apart from
00070  *   the lock bit form a pointer that points to the transaction
00071  *   descriptor containing the write-set.
00072  * If the lock bit is not set, then:
00073  * - All covered memory addresses contain consistent values.
00074  * - Write-back (ETL and CTL): all bits of the lock besides the lock bit
00075  *   contain a version number (timestamp).
00076  * - Write-through: all bits of the lock besides the lock bit contain a
00077  *   version number.
00078  *   - The high order bits contain the commit time.
00079  *   - The low order bits contain an incarnation number (incremented
00080  *     upon abort while writing the covered memory addresses).
00081  * When using the PRIORITY contention manager, the format of locks is
00082  * slightly different. It is documented elsewhere.
00083  */
00084 
00085 #define OWNED_MASK                      0x01                /* 1 bit */
00086 #if CM == CM_PRIORITY
00087 # define WAIT_MASK                      0x02                /* 1 bit */
00088 # define PRIORITY_BITS                  3                   /* 3 bits */
00089 # define PRIORITY_MAX                   ((1 << PRIORITY_BITS) - 1)
00090 # define PRIORITY_MASK                  (PRIORITY_MAX << 2)
00091 # define ALIGNMENT                      (1 << (PRIORITY_BITS + 2))
00092 #else
00093 # define ALIGNMENT                      1 /* no alignment requirement */  
00094 #endif /* CM == CM_PRIORITY */
00095 #define ALIGNMENT_MASK                 (ALIGNMENT - 1)
00096 
00097 /*
00098  * Everything hereafter relates to the actual locking protection mechanism.
00099  */
00100 #define LOCK_GET_OWNED(l)               ((l) & OWNED_MASK)
00101 #if CM == CM_PRIORITY
00102 # define LOCK_SET_ADDR(a, p)            ((a) | ((p) << 2) | OWNED_MASK)
00103 # define LOCK_GET_WAIT(l)               ((l) & WAIT_MASK)
00104 # define LOCK_GET_PRIORITY(l)           (((l) & PRIORITY_MASK) >> 2)
00105 # define LOCK_SET_PRIORITY_WAIT(l, p)   (((l) & ~(mtm_word_t)PRIORITY_MASK) | ((p) << 2) | WAIT_MASK)
00106 # define LOCK_GET_ADDR(l)               ((l) & ~(mtm_word_t)(OWNED_MASK | WAIT_MASK | PRIORITY_MASK))
00107 #else /* CM != CM_PRIORITY */
00108 # define LOCK_SET_ADDR(a)               ((a) | OWNED_MASK)    /* OWNED bit set */
00109 # define LOCK_GET_ADDR(l)               ((l) & ~(mtm_word_t)OWNED_MASK)
00110 #endif /* CM != CM_PRIORITY */
00111 #define LOCK_UNIT                       (~(mtm_word_t)0)
00112 
00113 /*
00114  * We use an array of locks and hash the address to find the location of the lock.
00115  * We try to avoid collisions as much as possible (two addresses covered by the same lock).
00116  */
00117 #define LOCK_ARRAY_SIZE                 (1 << LOCK_ARRAY_LOG_SIZE)
00118 #define LOCK_MASK                       (LOCK_ARRAY_SIZE - 1)
00119 //#define LOCK_SHIFT                      (((sizeof(mtm_word_t) == 4) ? 2 : 3) + LOCK_SHIFT_EXTRA)
00120 // Map the words of a cacheline on the same lock
00121 #define LOCK_SHIFT                      6
00122 #define LOCK_IDX(a)                     (((mtm_word_t)((a)) >> LOCK_SHIFT) & LOCK_MASK)
00123 #ifdef LOCK_IDX_SWAP
00124 # if LOCK_ARRAY_LOG_SIZE < 16
00125 #  error "LOCK_IDX_SWAP requires LOCK_ARRAY_LOG_SIZE to be at least 16"
00126 # endif /* LOCK_ARRAY_LOG_SIZE < 16 */
00127 # define GET_LOCK(a)                    (locks + lock_idx_swap(LOCK_IDX((a))))
00128 #else /* ! LOCK_IDX_SWAP */
00129 # define GET_LOCK(a)                    (locks + LOCK_IDX((a)))
00130 #endif /* ! LOCK_IDX_SWAP */
00131 
00132 
00133 
00134 /* ################################################################### *
00135  * PRIVATE PSEUDO-LOCKS
00136  * ################################################################### */
00137 
00138 /* 
00139  * For write-back, the original TinySTM keeps new values into linked lists
00140  * accessible through the global lock hash-table. 
00141  * 
00142  * For persistent write-back, when isolation is disabled, going through
00143  * the global lock hash-table would require fine-grain synchronization 
00144  * so that locks are not held for the duration of a transaction. To avoid 
00145  * paying the cost of such unnecessary synchronization we use a private lock 
00146  * hash-table instead. The structure of the private table is the same as 
00147  * the global one's to keep code changes minimal; its size may be different 
00148  * though.
00149  *
00150  * Private pseudo-locks are not actually locks but a hack to keep the code 
00151  * that deals with version-management common between the isolation and 
00152  * no-isolation path. Since never two threads may compete for these pseudo-locks, 
00153  * we don't need to use CAS to atomically acquire them but instead we can just 
00154  * set them using a normal STORE.
00155  */
00156  
00157 #define PRIVATE_LOCK_ARRAY_SIZE         (1 << PRIVATE_LOCK_ARRAY_LOG_SIZE)
00158 #define PRIVATE_LOCK_MASK               (PRIVATE_LOCK_ARRAY_SIZE - 1)
00159 #define PRIVATE_LOCK_SHIFT              6
00160 #define PRIVATE_LOCK_IDX(a)             (((mtm_word_t)((a)) >> PRIVATE_LOCK_SHIFT) & PRIVATE_LOCK_MASK)
00161 #define PRIVATE_GET_LOCK(tx, a)         (tx->wb_table + PRIVATE_LOCK_IDX((a)))
00162 
00163 
00164 #endif /* _LOCKS_H */

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