Skip to content

Commit b03bdba

Browse files
committed
trying out rtm
1 parent dd2c705 commit b03bdba

File tree

4 files changed

+44
-45
lines changed

4 files changed

+44
-45
lines changed

.clang-format

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Use the Google style in this project.
2+
BasedOnStyle: Google

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ include(FetchContent)
1111

1212
set(CMAKE_CXX_STANDARD 17)
1313

14-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long -pedantic -fPIC -march=native")
14+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long -pedantic -fPIC -mrtm -march=native")
1515

1616
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
1717
message("-- Release mode, all optimizations enabled")

src/mwcas/mwcas.cc

+41-42
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,10 @@ uint64_t Descriptor::CondCAS(uint32_t word_index, uint64_t dirty_flag) {
434434
return ret;
435435
}
436436

437-
#ifdef RTM
438437
bool Descriptor::RTMInstallDescriptors(uint64_t dirty_flag) {
439438
uint64_t mwcas_descptr = SetFlags(this, kMwCASFlag | dirty_flag);
440439
uint64_t tries = 0;
441-
static const uint64_t kMaxTries = 10000;
440+
static const uint64_t kMaxTries = 10;
442441

443442
retry:
444443
if(_XBEGIN_STARTED == _xbegin()) {
@@ -457,7 +456,6 @@ bool Descriptor::RTMInstallDescriptors(uint64_t dirty_flag) {
457456
}
458457
return false;
459458
}
460-
#endif
461459

462460
#ifndef PMEM
463461
bool Descriptor::VolatileMwCAS(uint32_t calldepth) {
@@ -644,56 +642,57 @@ bool Descriptor::PersistentMwCAS(uint32_t calldepth) {
644642
uint64_t descptr = SetFlags(this, kMwCASFlag | kDirtyFlag);
645643
uint32_t my_status = kStatusSucceeded;
646644

647-
#ifdef RTM
648645
// Go to phase 2 directly if helping along.
649-
if(calldepth > 0 && !RTMInstallDescriptors(kDirtyFlag)) {
646+
if (calldepth > 0) {
650647
my_status = kStatusFailed;
651648
}
652-
#else
653649

654-
for(uint32_t i = 0; i < count_ && my_status == kStatusSucceeded; ++i) {
655-
WordDescriptor* wd = &words_[i];
656-
// Skip entries added purely for allocating memory
657-
if((uint64_t)wd->address_ == Descriptor::kAllocNullAddress){
658-
continue;
659-
}
660-
retry_entry:
661-
auto rval = CondCAS(i, kDirtyFlag);
662-
663-
// Ok if a) we succeeded to swap in a pointer to this descriptor or b) some
664-
// other thread has already done so. Need to persist all fields (which point
665-
// to descriptors) before switching to final status, so that recovery will
666-
// know reliably whether to roll forward or back for this descriptor.
667-
if(rval == wd->old_value_ || CleanPtr(rval) == (uint64_t)this) {
668-
continue;
669-
}
670-
671-
if (rval & kDirtyFlag){
672-
goto retry_entry;
673-
}
650+
// Try RTM install first, if failed go to fallback solution.
651+
if (!RTMInstallDescriptors(kDirtyFlag)) {
652+
for (uint32_t i = 0; i < count_ && my_status == kStatusSucceeded; ++i) {
653+
WordDescriptor* wd = &words_[i];
654+
// Skip entries added purely for allocating memory
655+
if ((uint64_t)wd->address_ == Descriptor::kAllocNullAddress) {
656+
continue;
657+
}
658+
retry_entry:
659+
auto rval = CondCAS(i, kDirtyFlag);
660+
661+
// Ok if a) we succeeded to swap in a pointer to this descriptor or b)
662+
// some other thread has already done so. Need to persist all fields
663+
// (which point to descriptors) before switching to final status, so that
664+
// recovery will know reliably whether to roll forward or back for this
665+
// descriptor.
666+
if (rval == wd->old_value_ || CleanPtr(rval) == (uint64_t)this) {
667+
continue;
668+
}
674669

675-
// Do we need to help another MWCAS operation?
676-
if(IsMwCASDescriptorPtr(rval)) {
677-
#if PMWCAS_THREAD_HELP == 1
678670
if (rval & kDirtyFlag) {
679-
wd->PersistAddress();
680-
CompareExchange64(wd->address_, rval & ~kDirtyFlag, rval);
671+
goto retry_entry;
681672
}
682673

683-
// Clashed with another MWCAS; help complete the other MWCAS if it is
684-
// still in flight.
685-
Descriptor *otherMWCAS = (Descriptor *)CleanPtr(rval);
686-
otherMWCAS->PersistentMwCAS(calldepth + 1);
687-
MwCASMetrics::AddHelpAttempt();
674+
// Do we need to help another MWCAS operation?
675+
if (IsMwCASDescriptorPtr(rval)) {
676+
#if PMWCAS_THREAD_HELP == 1
677+
if (rval & kDirtyFlag) {
678+
wd->PersistAddress();
679+
CompareExchange64(wd->address_, rval & ~kDirtyFlag, rval);
680+
}
681+
682+
// Clashed with another MWCAS; help complete the other MWCAS if it is
683+
// still in flight.
684+
Descriptor* otherMWCAS = (Descriptor*)CleanPtr(rval);
685+
otherMWCAS->PersistentMwCAS(calldepth + 1);
686+
MwCASMetrics::AddHelpAttempt();
688687
#endif
689-
goto retry_entry;
690-
} else {
691-
// rval must be another value, we failed
692-
my_status = kStatusFailed;
688+
goto retry_entry;
689+
} else {
690+
// rval must be another value, we failed
691+
my_status = kStatusFailed;
692+
}
693693
}
694-
}
695-
#endif
696694

695+
}
697696
// Switch to the final state, the MwCAS concludes after this point
698697
CompareExchange32(&status_, my_status | kStatusDirtyFlag, kStatusUndecided);
699698

src/mwcas/mwcas.h

-2
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,7 @@ class alignas(kCacheLineSize) Descriptor {
250250
#endif
251251
}
252252

253-
#ifdef RTM
254253
bool RTMInstallDescriptors(uint64_t dirty_flag = 0);
255-
#endif
256254

257255
/// Retrieve the index position in the descriptor of the given address.
258256
int32_t GetInsertPosition(uint64_t* addr);

0 commit comments

Comments
 (0)