tlds
Transactional Operations for Linked Data Structures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
RedoRAWUtils.hpp
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2011
3  * University of Rochester Department of Computer Science
4  * and
5  * Lehigh University Department of Computer Science and Engineering
6  *
7  * License: Modified BSD
8  * Please see the file LICENSE.RSTM for licensing information
9  */
10 
11 #ifndef STM_REDO_RAW_CHECK_HPP
12 #define STM_REDO_RAW_CHECK_HPP
13 
14 #include <stm/config.h>
15 
16 /**
17  * Redo-log TMs all need to perform a read-after-write check in their read_rw
18  * barriers in order to find any previous transactional writes. This is
19  * complicated when we're byte logging, because we may have written only part
20  * of a word, and be attempting to read a superset of the word bytes.
21  *
22  * This file provides three config-dependent macros to assist in dealing with
23  * the case where we need to merge a read an write to get the "correct" value.
24  */
25 
26 #if defined(STM_WS_WORDLOG)
27 /**
28  * When we're word logging the RAW check is trivial. If we found the value it
29  * was returned as log.val, so we can simply return it.
30  */
31 #define REDO_RAW_CHECK(found, log, mask) \
32  if (__builtin_expect(found, false)) \
33  return log.val;
34 
35 /**
36  * When we're word logging the RAW check is trivial. If we found the value
37  * it was returned as log.val, so we can simply return it. ProfileApp
38  * version logs the event.
39  */
40 #define REDO_RAW_CHECK_PROFILEAPP(found, log, mask) \
41  if (__builtin_expect(found, false)) { \
42  ++profiles[0].read_rw_raw; \
43  return log.val; \
44  }
45 
46 /**
47  * No RAW cleanup is required when word logging, we can just return the
48  * unadulterated value from the log. ProfileApp version logs the event.
49  */
50 #define REDO_RAW_CLEANUP(val, found, log, mask)
51 
52 #elif defined(STM_WS_BYTELOG)
53 
54 /**
55  * When we are byte logging and the writeset says that it found the address
56  * we're looking for, it could mean one of two things. We found the requested
57  * address, and the requested mask is a subset of the logged mask, or we found
58  * some of the bytes that were requested. The log.mask tells us which of the
59  * returned bytes in log.val are valid.
60  *
61  * We perform a subset test (i.e., mask \in log.mask) and just return log.val
62  * if it's successful. If mask isn't a subset of log.mask we'll deal with it
63  * during REDO_RAW_CLEANUP.
64  */
65 #define REDO_RAW_CHECK(found, log, pmask) \
66  if (__builtin_expect(found, false)) \
67  if ((pmask & log.mask) == pmask) \
68  return log.val;
69 
70 /**
71  * ProfileApp version logs the event.
72  *
73  * NB: Byte logging exposes new possible statistics, should we record them?
74  */
75 #define REDO_RAW_CHECK_PROFILEAPP(found, log, pmask) \
76  if (__builtin_expect(found, false)) { \
77  if ((pmask & log.mask) == pmask) { \
78  ++profiles[0].read_rw_raw; \
79  return log.val; \
80  } \
81  }
82 
83 /**
84  * When we're byte logging we may have had a partial RAW hit, i.e., the
85  * write log had some of the bytes that we needed, but not all.
86  *
87  * Check for a partial hit. If we had one, we need to mask out the recently
88  * read bytes that correspond to the valid bytes from the log, and then merge
89  * in the logged bytes.
90  */
91 #define REDO_RAW_CLEANUP(value, found, log, mask) \
92  if (__builtin_expect(found, false)) { \
93  /* can't do masking on a void* */ \
94  uintptr_t v = reinterpret_cast<uintptr_t>(value); \
95  v &= ~log.mask; \
96  v |= reinterpret_cast<uintptr_t>(log.val) & log.mask; \
97  value = reinterpret_cast<void*>(v); \
98  }
99 
100 #else
101 #error "Preprocessor configuration error: STM_WS_(WORD|BYTE)LOG not defined."
102 #endif
103 
104 #endif // STM_REDO_RAW_CHECK_HPP