diff options
Diffstat (limited to 'libitm/config/posix/rwlock.h')
-rw-r--r-- | libitm/config/posix/rwlock.h | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/libitm/config/posix/rwlock.h b/libitm/config/posix/rwlock.h index 81c29a6f426..1e74e64b87d 100644 --- a/libitm/config/posix/rwlock.h +++ b/libitm/config/posix/rwlock.h @@ -46,9 +46,9 @@ struct gtm_thread; // read-to-write upgrades do not have a higher priority than writers. // // Do not change the layout of this class; it must remain a POD type with -// standard layout, and the SUMMARY field must be first (i.e., so the +// standard layout, and the summary field must be first (i.e., so the // assembler code can assume that its address is equal to the address of the -// respective instance of the class). +// respective instance of the class), and htm_fastpath must be second. class gtm_rwlock { @@ -58,6 +58,13 @@ class gtm_rwlock std::atomic<unsigned int> summary; // Bitmask of the above. + // We put the HTM fastpath control variable here so that HTM fastpath + // transactions can check efficiently whether they are allowed to run. + // This must be accessed atomically because threads can load this value + // when they are neither a registered reader nor writer (i.e., when they + // attempt to execute the HTM fastpath). + std::atomic<uint32_t> htm_fastpath; + pthread_mutex_t mutex; // Held if manipulating any field. pthread_cond_t c_readers; // Readers wait here pthread_cond_t c_writers; // Writers wait here for writers @@ -80,12 +87,28 @@ class gtm_rwlock bool write_upgrade (gtm_thread *tx); void write_upgrade_finish (gtm_thread *tx); - // Returns true iff there is a concurrent active or waiting writer. - // This is primarily useful for simple HyTM approaches, and the value being - // checked is loaded with memory_order_relaxed. - bool is_write_locked() + // Returns true iff there is a concurrent active or waiting writer, or + // htm_fastpath is zero. This is primarily useful for simple HyTM + // approaches, and the values being checked are loaded with + // memory_order_relaxed. + bool htm_fastpath_disabled () + { + return (summary.load (memory_order_relaxed) & (a_writer | w_writer)) + || htm_fastpath.load (memory_order_relaxed) == 0; + } + + // This does not need to return an exact value, hence relaxed MO is + // sufficient. + uint32_t get_htm_fastpath () + { + return htm_fastpath.load (memory_order_relaxed); + } + // This must only be called while having acquired the write lock, and other + // threads do not need to load an exact value; hence relaxed MO is + // sufficient. + void set_htm_fastpath (uint32_t val) { - return summary.load (memory_order_relaxed) & (a_writer | w_writer); + htm_fastpath.store (val, memory_order_relaxed); } protected: |