Skip to content

Commit 352d0af

Browse files
committed
Switch from boost::thread to std::thread
1 parent 36435d2 commit 352d0af

34 files changed

+135
-116
lines changed

GNUmakefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ endif
6060
# -Winline
6161

6262
LIBS := $(EXTRALIBS) -lpcrecpp -lboost_program_options -lprotobuf -lrt \
63-
-lpthread -lboost_thread -lssl -lcrypto
63+
-lpthread -lssl -lcrypto
6464
ifeq ($(DEBUG),yes)
6565
# -rdynamic generates more useful backtraces when you have debugging symbols
6666
LIBS += -rdynamic

src/BackupService.cc

+6-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414
*/
1515

16-
#include <boost/thread.hpp>
16+
#include <thread>
1717

1818
#include "BackupService.h"
1919
#include "BackupStorage.h"
@@ -150,7 +150,7 @@ Status
150150
BackupService::SegmentInfo::appendRecoverySegment(uint64_t partitionId,
151151
Buffer& buffer)
152152
{
153-
Lock lock(mutex, boost::try_to_lock_t());
153+
Lock lock(mutex, std::try_to_lock_t());
154154
if (!lock.owns_lock()) {
155155
LOG(DEBUG, "Deferring because couldn't acquire lock immediately");
156156
return STATUS_RETRY;
@@ -649,7 +649,7 @@ BackupService::IoScheduler::store(SegmentInfo& info)
649649
* returns.
650650
*/
651651
void
652-
BackupService::IoScheduler::shutdown(boost::thread& ioThread)
652+
BackupService::IoScheduler::shutdown(std::thread& ioThread)
653653
{
654654
{
655655
Lock lock(queueMutex);
@@ -875,7 +875,7 @@ BackupService::BackupService(const Config& config,
875875
#ifdef SINGLE_THREADED_BACKUP
876876
, ioThread()
877877
#else
878-
, ioThread(boost::ref(ioScheduler))
878+
, ioThread(std::ref(ioScheduler))
879879
#endif
880880
, initCalled(false)
881881
{
@@ -1299,7 +1299,8 @@ BackupService::startReadingData(
12991299
partitions,
13001300
recoveryThreadCount);
13011301
++recoveryThreadCount;
1302-
boost::thread builderThread(builder);
1302+
std::thread builderThread(builder);
1303+
builderThread.detach();
13031304
LOG(DEBUG, "Kicked off building recovery segments; "
13041305
"main thread going back to dispatching requests");
13051306
#endif

src/BackupService.h

+11-11
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#else
2929
#include <cstdatomic>
3030
#endif
31-
#include <boost/thread.hpp>
31+
#include <thread>
3232
#include <boost/scoped_ptr.hpp>
3333
#include <boost/pool/pool.hpp>
3434
#include <map>
@@ -108,7 +108,7 @@ class BackupService : public Service {
108108
typedef boost::pool<SegmentAllocator> Pool;
109109

110110
/// The type of lock used to make access to #pool thread safe.
111-
typedef boost::unique_lock<boost::mutex> Lock;
111+
typedef std::unique_lock<std::mutex> Lock;
112112

113113
explicit ThreadSafePool(uint32_t chunkSize)
114114
: allocatedChunks()
@@ -162,7 +162,7 @@ class BackupService : public Service {
162162
uint32_t allocatedChunks;
163163

164164
/// Used to serialize access to #pool and #allocatedChunks.
165-
boost::mutex mutex;
165+
std::mutex mutex;
166166

167167
/// The backing pool that manages memory chunks.
168168
Pool pool;
@@ -179,7 +179,7 @@ class BackupService : public Service {
179179
class SegmentInfo {
180180
public:
181181
/// The type of locks used to lock #mutex.
182-
typedef boost::unique_lock<boost::mutex> Lock;
182+
typedef std::unique_lock<std::mutex> Lock;
183183

184184
/**
185185
* Tracks current state of the segment which is sufficient to
@@ -319,14 +319,14 @@ class BackupService : public Service {
319319
* Provides mutal exclusion between all public method calls and
320320
* storage operations that can be performed on SegmentInfos.
321321
*/
322-
boost::mutex mutex;
322+
std::mutex mutex;
323323

324324
/**
325325
* Notified when a store or load for this segment completes, or
326326
* when this segment's recovery segments are constructed and valid.
327327
* Used in conjunction with #mutex.
328328
*/
329-
boost::condition_variable condition;
329+
std::condition_variable condition;
330330

331331
/// Gatekeeper through which async IOs are scheduled.
332332
IoScheduler& ioScheduler;
@@ -404,19 +404,19 @@ class BackupService : public Service {
404404
void load(SegmentInfo& info);
405405
void quiesce();
406406
void store(SegmentInfo& info);
407-
void shutdown(boost::thread& ioThread);
407+
void shutdown(std::thread& ioThread);
408408

409409
private:
410410
void doLoad(SegmentInfo& info) const;
411411
void doStore(SegmentInfo& info) const;
412412

413-
typedef boost::unique_lock<boost::mutex> Lock;
413+
typedef std::unique_lock<std::mutex> Lock;
414414

415415
/// Protects #loadQueue, #storeQueue, and #running.
416-
boost::mutex queueMutex;
416+
std::mutex queueMutex;
417417

418418
/// Notified when new requests are added to either queue.
419-
boost::condition_variable queueCond;
419+
std::condition_variable queueCond;
420420

421421
/// Queue of SegmentInfos to be loaded from storage.
422422
std::queue<SegmentInfo*> loadQueue;
@@ -582,7 +582,7 @@ class BackupService : public Service {
582582
/// Gatekeeper through which async IOs are scheduled.
583583
IoScheduler ioScheduler;
584584
/// The thread driving #ioScheduler.
585-
boost::thread ioThread;
585+
std::thread ioThread;
586586

587587
/// Used to ensure that init() is invoked before the dispatcher runs.
588588
bool initCalled;

src/BackupServiceTest.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ class SegmentInfoTest : public ::testing::Test {
759759
, pool{segmentSize}
760760
, storage{segmentSize, 2}
761761
, ioScheduler()
762-
, ioThread(boost::ref(ioScheduler))
762+
, ioThread(std::ref(ioScheduler))
763763
, info{storage, pool, ioScheduler,
764764
ServerId(99, 0), 88, segmentSize, true}
765765
{
@@ -774,7 +774,7 @@ class SegmentInfoTest : public ::testing::Test {
774774
BackupService::ThreadSafePool pool;
775775
InMemoryStorage storage;
776776
BackupService::IoScheduler ioScheduler;
777-
boost::thread ioThread;
777+
std::thread ioThread;
778778
SegmentInfo info;
779779
};
780780

src/BackupStorageBenchmark.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414
*/
1515

16-
#include <boost/thread/thread.hpp>
16+
#include <thread>
1717

1818
#include "BackupStorage.h"
1919
#include "Cycles.h"
@@ -125,7 +125,7 @@ struct Bench {
125125
int i = 0;
126126
foreach (auto* handle, allocated) {
127127
if (!(i++ % 3))
128-
boost::thread(Store(storage, scratch, *(writeHandle++)));
128+
std::thread(Store(storage, scratch, *(writeHandle++)));
129129
uint64_t start = Cycles::rdtsc();
130130
storage.getSegment(handle, scratch);
131131
uint64_t getTime = Cycles::rdtsc() - start;

src/Dispatch.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
#else
2222
#include <cstdatomic>
2323
#endif
24-
#include <boost/thread.hpp>
25-
#include <boost/thread/locks.hpp>
24+
#include <thread>
2625

2726
#include "Common.h"
2827
#include "AtomicInt.h"
@@ -229,7 +228,7 @@ class Dispatch {
229228
/// is constructed in a thread other than the dispatch thread
230229
/// (no mutual exclusion is needed if the Lock is created in
231230
/// the dispatch thread).
232-
Tub<boost::lock_guard<SpinLock>> lock;
231+
Tub<std::lock_guard<SpinLock>> lock;
233232
DISALLOW_COPY_AND_ASSIGN(Lock);
234233
};
235234

@@ -253,7 +252,7 @@ class Dispatch {
253252
// We start a separate thread to invoke epoll kernel calls, so the
254253
// main polling loop is not delayed by kernel calls. This thread
255254
// is only used when there are active Files.
256-
Tub<boost::thread> epollThread;
255+
Tub<std::thread> epollThread;
257256

258257
// Read and write descriptors for a pipe. The epoll thread always has
259258
// the read fd for this pipe in its active set; writing data to the pipe

src/DispatchTest.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ TEST_F(DispatchTest, poll_locking) {
315315
// from there.
316316
CountPoller* counter = NULL;
317317
volatile int flag = 0;
318-
boost::thread thread(lockTestThread, &Context::get(), &flag, &counter);
318+
std::thread thread(lockTestThread, &Context::get(), &flag, &counter);
319319
Dispatch& dispatch = *Context::get().dispatch;
320320

321321
// Wait for the child thread to start up and enter its polling loop.
@@ -480,7 +480,7 @@ TEST_F(DispatchTest, isDispatchThread) {
480480
td->hasDedicatedThread = true;
481481
EXPECT_TRUE(td->isDispatchThread());
482482
bool childResult = true;
483-
boost::thread(checkDispatchThread, td, &childResult).join();
483+
std::thread(checkDispatchThread, td, &childResult).join();
484484
EXPECT_FALSE(childResult);
485485
}
486486

@@ -734,7 +734,7 @@ TEST_F(DispatchTest, epollThreadMain_signalEventsAndExit) {
734734

735735
// Start up the polling thread; it will signal the first ready file.
736736
td->readyFd = -1;
737-
boost::thread(epollThreadWrapper, &Context::get()).detach();
737+
std::thread(epollThreadWrapper, &Context::get()).detach();
738738
waitForReadyFd(1.0);
739739
EXPECT_EQ(43, td->readyFd);
740740
EXPECT_EQ(Dispatch::FileEvent::WRITABLE, td->readyEvents);

src/FailureDetector.cc

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "Common.h"
2020
#include "Cycles.h"
21+
#include "Fence.h"
2122
#include "PingClient.h"
2223
#include "CoordinatorClient.h"
2324
#include "FailureDetector.h"
@@ -51,6 +52,7 @@ FailureDetector::FailureDetector(const string &coordinatorLocatorString,
5152
: ourServerId(ourServerId),
5253
serverTracker(serverList),
5354
thread(),
55+
threadShouldExit(false),
5456
pingClient(),
5557
coordinatorClient(coordinatorLocatorString.c_str()),
5658
serverList(serverList),
@@ -88,8 +90,10 @@ void
8890
FailureDetector::halt()
8991
{
9092
if (thread) {
91-
thread->interrupt();
93+
threadShouldExit = true;
94+
Fence::sfence();
9295
thread->join();
96+
threadShouldExit = false;
9397
thread.destroy();
9498
}
9599
}
@@ -113,7 +117,9 @@ FailureDetector::detectorThreadEntry(FailureDetector* detector,
113117

114118
while (1) {
115119
// Check if we have been requested to exit.
116-
boost::this_thread::interruption_point();
120+
Fence::lfence();
121+
if (detector->threadShouldExit)
122+
break;
117123

118124
// Drain the list of changes to update our tracker.
119125
ServerChangeDetails dummy1;

src/FailureDetector.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndef RAMCLOUD_FAILUREDETECTOR_H
1717
#define RAMCLOUD_FAILUREDETECTOR_H
1818

19+
#include <thread>
1920
#include <list>
2021

2122
#include "Common.h"
@@ -84,7 +85,10 @@ class FailureDetector {
8485
ServerTracker<bool> serverTracker;
8586

8687
/// Failure detector thread
87-
Tub<boost::thread> thread;
88+
Tub<std::thread> thread;
89+
90+
/// Set by halt() to ask the failure detector thread to exit.
91+
bool threadShouldExit;
8892

8993
// Service Clients
9094
/// PingClient instance

src/Log.cc

+10-10
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Log::allocateHead()
146146
// if you don't know why this is bad.
147147
LogDigest::SegmentId newHeadId = allocateSegmentId();
148148

149-
boost::lock_guard<SpinLock> lock(listLock);
149+
std::lock_guard<SpinLock> lock(listLock);
150150

151151
if (head != NULL)
152152
cleanableNewList.push_back(*head);
@@ -207,7 +207,7 @@ Log::allocateHead()
207207
bool
208208
Log::isSegmentLive(uint64_t segmentId)
209209
{
210-
boost::lock_guard<SpinLock> lock(listLock);
210+
std::lock_guard<SpinLock> lock(listLock);
211211
return (activeIdMap.find(segmentId) != activeIdMap.end());
212212
}
213213

@@ -504,7 +504,7 @@ void *
504504
Log::getSegmentMemoryForCleaning(bool useEmergencyReserve)
505505
{
506506
if (useEmergencyReserve) {
507-
boost::lock_guard<SpinLock> lock(listLock);
507+
std::lock_guard<SpinLock> lock(listLock);
508508

509509
if (emergencyCleanerList.empty())
510510
return NULL;
@@ -523,7 +523,7 @@ Log::getSegmentMemoryForCleaning(bool useEmergencyReserve)
523523
size_t
524524
Log::freeListCount()
525525
{
526-
boost::lock_guard<SpinLock> lock(listLock);
526+
std::lock_guard<SpinLock> lock(listLock);
527527

528528
// We always save one for the next Log head, so adjust accordingly.
529529
return (freeList.size() > 0) ? freeList.size() - 1 : freeList.size();
@@ -540,7 +540,7 @@ Log::freeListCount()
540540
void
541541
Log::getNewCleanableSegments(SegmentVector& out)
542542
{
543-
boost::lock_guard<SpinLock> lock(listLock);
543+
std::lock_guard<SpinLock> lock(listLock);
544544

545545
while (!cleanableNewList.empty()) {
546546
Segment& s = cleanableNewList.front();
@@ -564,7 +564,7 @@ Log::getNewCleanableSegments(SegmentVector& out)
564564
void
565565
Log::cleaningInto(Segment* segment)
566566
{
567-
boost::lock_guard<SpinLock> lock(listLock);
567+
std::lock_guard<SpinLock> lock(listLock);
568568

569569
cleaningIntoList.push_back(*segment);
570570
activeIdMap[segment->getId()] = segment;
@@ -592,7 +592,7 @@ void
592592
Log::cleaningComplete(SegmentVector& clean,
593593
std::vector<void*>& unusedSegmentMemory)
594594
{
595-
boost::lock_guard<SpinLock> lock(listLock);
595+
std::lock_guard<SpinLock> lock(listLock);
596596
bool change = false;
597597

598598
// Return any unused segment memory the cleaner ended up
@@ -673,7 +673,7 @@ uint64_t
673673
Log::allocateSegmentId()
674674
{
675675
// XXX- could just be an atomic op
676-
boost::lock_guard<SpinLock> lock(listLock);
676+
std::lock_guard<SpinLock> lock(listLock);
677677
return nextSegmentId++;
678678
}
679679

@@ -792,7 +792,7 @@ Log::locklessAddToFreeList(void *p)
792792
void *
793793
Log::getFromFreeList(bool mayUseLastSegment)
794794
{
795-
boost::lock_guard<SpinLock> lock(listLock);
795+
std::lock_guard<SpinLock> lock(listLock);
796796

797797
if (freeList.empty())
798798
throw LogOutOfMemoryException(HERE, "Log is out of space");
@@ -837,7 +837,7 @@ Log::getSegmentFromAddress(const void* address)
837837
{
838838
const void *base = Segment::getSegmentBaseAddress(address, segmentCapacity);
839839

840-
boost::lock_guard<SpinLock> lock(listLock);
840+
std::lock_guard<SpinLock> lock(listLock);
841841

842842
if (head != NULL && base == head->getBaseAddress())
843843
return head;

0 commit comments

Comments
 (0)