summaryrefslogtreecommitdiff
path: root/libitm/config/posix/rwlock.h
diff options
context:
space:
mode:
Diffstat (limited to 'libitm/config/posix/rwlock.h')
-rw-r--r--libitm/config/posix/rwlock.h37
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: