tlds
Transactional Operations for Linked Data Structures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
stm::ByteLoggingWriteSetEntry Struct Reference

#include <WriteSet.hpp>

Collaboration diagram for stm::ByteLoggingWriteSetEntry:

Public Member Functions

 ByteLoggingWriteSetEntry (void **paddr, void *pval, uintptr_t pmask)
 
void update (const ByteLoggingWriteSetEntry &rhs)
 
bool filter (void **lower, void **upper)
 
void writeback () const
 
void rollback (void **lower, void **upper)
 

Public Attributes

union {
   void **   addr
 
   uint8_t *   byte_addr
 
}; 
 
union {
   void *   val
 
   uint8_t   byte_val [sizeof(void *)]
 
}; 
 
union {
   uintptr_t   mask
 
   uint8_t   byte_mask [sizeof(void *)]
 
}; 
 

Detailed Description

The log entry for byte logging is complicated by

1) the fact that we store a bitmask 2) that we need to treat the address/value/mask instance variables as both word types, and byte types.

We do this with unions, which makes the use of these easier since it reduces the huge number of casts we perform otherwise.

Union naming is important, since the outside world only directly deals with the word-sized fields.

Constructor & Destructor Documentation

stm::ByteLoggingWriteSetEntry::ByteLoggingWriteSetEntry ( void **  paddr,
void *  pval,
uintptr_t  pmask 
)
inline

Member Function Documentation

bool stm::ByteLoggingWriteSetEntry::filter ( void **  lower,
void **  upper 
)
inline

Check to see if the entry is completely contained within the given address range. We have some preconditions here w.r.t. alignment and size of the range. It has to be at least word aligned and word sized. This is currently only used with stack addresses, so we don't include asserts because we don't want to pay for them in the common case writeback loop.

The byte-logging writeset can actually accommodate awkward intersections here using the mask, but we're not going to worry about that given the expected size/alignment of the range.

void stm::ByteLoggingWriteSetEntry::rollback ( void **  lower,
void **  upper 
)
inline

Called during the rollback loop in order to write out buffered writes to an exception object (represented by the address range). We don't assume anything about the alignment or size of the exception object.

Here is the call graph for this function:

void stm::ByteLoggingWriteSetEntry::update ( const ByteLoggingWriteSetEntry rhs)
inline

Called when we are WAW an address, and we want to coalesce the write. Trivial for the word-based writeset, but complicated for the byte-based version.

The new value is the bytes from the incoming log injected into the existing value, we mask out the bytes we want from the incoming word, mask the existing word, and union them.

void stm::ByteLoggingWriteSetEntry::writeback ( ) const
inline

If we're byte-logging, we'll write out each byte individually when we're not writing a whole word. This turns all subword writes into byte writes, so we lose the original atomicity of (say) half-word writes in the original source. This isn't a correctness problem because of our transactional synchronization, but could be a performance problem if the system depends on sub-word writes for performance.

Here is the caller graph for this function:

Member Data Documentation

union { ... }
union { ... }
union { ... }
void** stm::ByteLoggingWriteSetEntry::addr
uint8_t* stm::ByteLoggingWriteSetEntry::byte_addr
uint8_t stm::ByteLoggingWriteSetEntry::byte_mask[sizeof(void *)]
uint8_t stm::ByteLoggingWriteSetEntry::byte_val[sizeof(void *)]
uintptr_t stm::ByteLoggingWriteSetEntry::mask
void* stm::ByteLoggingWriteSetEntry::val

The documentation for this struct was generated from the following file: