summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-10-07 20:29:40 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-10-07 20:53:05 +0000
commit356172042cbc96375be8d663a945879b9f10dd41 (patch)
treee77fb1af93766b3655df04a55a9fa5dee6ef7971 /vespalib
parent379b3d8c3ce128da5a985ed73fce99326369512c (diff)
- GC unused code.
- vespalib::Lock -> std::mutex
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/CMakeLists.txt2
-rw-r--r--vespalib/src/tests/delegatelist/.cvsignore3
-rw-r--r--vespalib/src/tests/delegatelist/.gitignore4
-rw-r--r--vespalib/src/tests/delegatelist/CMakeLists.txt8
-rw-r--r--vespalib/src/tests/delegatelist/delegatelist.cpp824
-rw-r--r--vespalib/src/tests/rwlock/.gitignore4
-rw-r--r--vespalib/src/tests/rwlock/CMakeLists.txt8
-rw-r--r--vespalib/src/tests/rwlock/rwlock_test.cpp78
-rw-r--r--vespalib/src/tests/sync/sync_test.cpp131
-rw-r--r--vespalib/src/vespa/vespalib/data/memorydatastore.cpp3
-rw-r--r--vespalib/src/vespa/vespalib/data/memorydatastore.h6
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.cpp34
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.h19
-rw-r--r--vespalib/src/vespa/vespalib/testkit/test_master.hpp2
-rw-r--r--vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--vespalib/src/vespa/vespalib/util/alloc.cpp8
-rw-r--r--vespalib/src/vespa/vespalib/util/delegatelist.hpp309
-rw-r--r--vespalib/src/vespa/vespalib/util/ptrholder.h14
-rw-r--r--vespalib/src/vespa/vespalib/util/rwlock.cpp59
-rw-r--r--vespalib/src/vespa/vespalib/util/rwlock.h240
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp4
-rw-r--r--vespalib/src/vespa/vespalib/util/simple_thread_bundle.h5
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.cpp47
-rw-r--r--vespalib/src/vespa/vespalib/util/sync.h104
24 files changed, 87 insertions, 1830 deletions
diff --git a/vespalib/CMakeLists.txt b/vespalib/CMakeLists.txt
index ec003329999..278d32c118d 100644
--- a/vespalib/CMakeLists.txt
+++ b/vespalib/CMakeLists.txt
@@ -46,7 +46,6 @@ vespa_define_module(
src/tests/datastore/unique_store
src/tests/datastore/unique_store_dictionary
src/tests/datastore/unique_store_string_allocator
- src/tests/delegatelist
src/tests/detect_type_benchmark
src/tests/dotproduct
src/tests/drop-file-from-cache
@@ -94,7 +93,6 @@ vespa_define_module(
src/tests/regex
src/tests/rendezvous
src/tests/runnable_pair
- src/tests/rwlock
src/tests/sha1
src/tests/sharedptr
src/tests/signalhandler
diff --git a/vespalib/src/tests/delegatelist/.cvsignore b/vespalib/src/tests/delegatelist/.cvsignore
deleted file mode 100644
index 0e8f4d0be0b..00000000000
--- a/vespalib/src/tests/delegatelist/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.depend
-Makefile
-delegatelist_test
diff --git a/vespalib/src/tests/delegatelist/.gitignore b/vespalib/src/tests/delegatelist/.gitignore
deleted file mode 100644
index 42ac4beb0c3..00000000000
--- a/vespalib/src/tests/delegatelist/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.depend
-Makefile
-delegatelist_test
-vespalib_delegatelist_test_app
diff --git a/vespalib/src/tests/delegatelist/CMakeLists.txt b/vespalib/src/tests/delegatelist/CMakeLists.txt
deleted file mode 100644
index 71551474445..00000000000
--- a/vespalib/src/tests/delegatelist/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(vespalib_delegatelist_test_app TEST
- SOURCES
- delegatelist.cpp
- DEPENDS
- vespalib
-)
-vespa_add_test(NAME vespalib_delegatelist_test_app COMMAND vespalib_delegatelist_test_app)
diff --git a/vespalib/src/tests/delegatelist/delegatelist.cpp b/vespalib/src/tests/delegatelist/delegatelist.cpp
deleted file mode 100644
index 4dc7e5c97d7..00000000000
--- a/vespalib/src/tests/delegatelist/delegatelist.cpp
+++ /dev/null
@@ -1,824 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/delegatelist.hpp>
-#include <vespa/vespalib/util/guard.h>
-#include <vespa/fastos/thread.h>
-#include <queue>
-
-#include <vespa/log/log.h>
-LOG_SETUP("delegatelist_test");
-
-using namespace vespalib;
-
-//-----------------------------------------------------------------------------
-
-class Test : public TestApp
-{
-public:
- void testEmpty();
- void testAdd();
- void testRemove();
- void testOneShot();
- void testMultiSnapshot();
- void testActors();
- void testWaitSnapshots();
- void stressTest();
- int Main() override;
-};
-
-//-----------------------------------------------------------------------------
-
-namespace {
-
-class Handler
-{
-private:
- int _num;
-public:
- Handler() : _num(0) {}
- void add() { _num++; }
- int getNum() { return _num; }
-};
-
-typedef DelegateList<Handler> DL;
-
-void multicast(DL &dl) {
- for (DL::Snapshot snap(dl) ; snap.valid(); snap.next()) {
- snap.get()->add();
- }
-}
-
-void multicast_clear(DL &dl) {
- DL::Snapshot snap(dl);
- dl.clear();
- for (; snap.valid(); snap.next()) {
- snap.get()->add();
- }
-}
-
-//-----------------------------------------------------------------------------
-
-enum {
- CMD_MULTICAST,
- CMD_MULTICAST_CLEAR,
- CMD_ADD,
- CMD_REMOVE,
- CMD_CLEAR,
- CMD_WAIT_SNAP,
- CMD_DO,
- CMD_DONE,
- CMD_EXIT
-};
-
-struct Command
-{
- DL *dl;
- int cmd;
- int cnt;
- Handler *handler;
- Command(DL *dl_, int cmd_, int cnt_, Handler *handler_) noexcept
- : dl(dl_), cmd(cmd_), cnt(cnt_), handler(handler_) {}
- Command(const Command &rhs) noexcept
- : dl(rhs.dl), cmd(rhs.cmd), cnt(rhs.cnt), handler(rhs.handler) {}
- Command &operator=(const Command &rhs) noexcept {
- memcpy(this, &rhs, sizeof(Command));
- return *this;
- }
- bool operator==(const Command &rhs) noexcept {
- return memcmp(this, &rhs, sizeof(Command)) == 0;
- }
-};
-
-Command
-cmd_multicast(DL *dl) {
- return Command(dl, CMD_MULTICAST, 0, 0);
-}
-
-Command
-cmd_multicast_clear(DL *dl) {
- return Command(dl, CMD_MULTICAST_CLEAR, 0, 0);
-}
-
-Command
-cmd_add(DL *dl, Handler *handler) {
- return Command(dl, CMD_ADD, 0, handler);
-}
-
-Command
-cmd_remove(DL *dl, Handler *handler) {
- return Command(dl, CMD_REMOVE, 0, handler);
-}
-
-Command
-cmd_clear(DL *dl) {
- return Command(dl, CMD_CLEAR, 0, 0);
-}
-
-Command
-cmd_wait_snap(DL *dl) {
- return Command(dl, CMD_WAIT_SNAP, 0, 0);
-}
-
-Command
-cmd_do(int cnt) {
- return Command(0, CMD_DO, cnt, 0);
-}
-
-Command
-cmd_done() {
- return Command(0, CMD_DONE, 0, 0);
-}
-
-Command
-cmd_exit() {
- return Command(0, CMD_EXIT, 0, 0);
-}
-
-typedef std::vector<Command> CmdList;
-typedef std::pair<Command, int> HistEntry;
-typedef std::vector<HistEntry> HistList;
-
-//-----------------------------------------------------------------------------
-
-struct History {
- Lock lock;
- HistList list;
- History() : lock(), list() {}
- void add(const HistEntry &entry) {
- LockGuard guard(lock);
- list.push_back(entry);
- }
-};
-
-//-----------------------------------------------------------------------------
-
-template <typename T>
-class Queue {
-private:
- std::queue<T> _q;
- Monitor _cond;
- int _waitCnt;
- Queue(const Queue &);
- Queue &operator=(const Queue &);
-public:
- Queue() : _q(), _cond(), _waitCnt(0) {}
- void enqueue(const T &entry) {
- MonitorGuard guard(_cond);
- _q.push(entry);
- if (_waitCnt > 0) {
- guard.signal();
- }
- }
- T dequeue() {
- MonitorGuard guard(_cond);
- CounterGuard cntGuard(_waitCnt);
- while (_q.empty()) {
- guard.wait();
- }
- T tmp = _q.front();
- _q.pop();
- return tmp;
- }
- size_t size() const { return _q.size(); }
-};
-
-typedef Queue<CmdList> CmdListQueue;
-
-//-----------------------------------------------------------------------------
-
-class Actor : public FastOS_Runnable
-{
-public:
- enum {
- STATE_INIT,
- STATE_IDLE,
- STATE_BUSY,
- STATE_DONE
- };
-private:
- int _id;
- History *_hist;
- CmdListQueue _queue;
- Monitor _cond;
- int _state;
- int _waitCnt;
- int _opCnt;
- bool _exit;
- Actor(const Actor &);
- Actor &operator=(const Actor &);
- void setState(int state, MonitorGuard &guard);
- void doneOp(const Command &cmd);
- int perform(int cnt, int start, const CmdList &cmdList);
-public:
- Actor(int id, History *hist);
- ~Actor();
- int getOpCnt() const { return _opCnt; }
- int getState() const { return _state; }
- void doIt(const CmdList &cmdList);
- void doIt(const Command &cmd);
- void waitState(int state);
- void Run(FastOS_ThreadInterface *, void *) override;
-};
-
-Actor::Actor(int id, History *hist)
- : _id(id), _hist(hist), _queue(), _cond(), _state(STATE_INIT),
- _waitCnt(0), _opCnt(0), _exit(false)
-{}
-Actor::~Actor() {}
-
-void
-Actor::setState(int state, MonitorGuard &guard) {
- _state = state;
- if (_waitCnt > 0) {
- guard.broadcast();
- }
-}
-
-
-void
-Actor::doneOp(const Command &cmd)
-{
- ++_opCnt;
- if (_hist != 0) {
- _hist->add(HistEntry(cmd, _id));
- }
-}
-
-
-int
-Actor::perform(int cnt, int start, const CmdList &cmdList)
-{
- int doneIdx = cmdList.size();
- for (int i = 0; i < cnt; ++i) {
- for (uint32_t idx = start; idx < cmdList.size(); ++idx) {
- Command cmd = cmdList[idx];
- switch (cmd.cmd) {
- case CMD_MULTICAST:
- multicast(*cmd.dl);
- doneOp(cmd);
- break;
- case CMD_MULTICAST_CLEAR:
- multicast_clear(*cmd.dl);
- doneOp(cmd);
- break;
- case CMD_ADD:
- cmd.dl->add(cmd.handler);
- doneOp(cmd);
- break;
- case CMD_REMOVE:
- cmd.dl->remove(cmd.handler);
- doneOp(cmd);
- break;
- case CMD_CLEAR:
- cmd.dl->clear();
- doneOp(cmd);
- break;
- case CMD_WAIT_SNAP:
- cmd.dl->waitSnapshots();
- doneOp(cmd);
- break;
- case CMD_DO:
- idx = perform(cmd.cnt, idx + 1, cmdList);
- break;
- case CMD_DONE:
- doneIdx = idx;
- idx = cmdList.size();
- break;
- case CMD_EXIT:
- _exit = true;
- return cmdList.size();
- break;
- default:
- LOG_ABORT("should not be reached"); // that does not seem to work
- }
- }
- }
- return doneIdx;
-}
-
-
-void
-Actor::doIt(const CmdList &cmdList)
-{
- MonitorGuard guard(_cond);
- setState(STATE_BUSY, guard);
- _queue.enqueue(cmdList);
-}
-
-
-void
-Actor::doIt(const Command &cmd)
-{
- CmdList cmdList;
- cmdList.push_back(cmd);
- doIt(cmdList);
-}
-
-
-void
-Actor::waitState(int state) {
- MonitorGuard guard(_cond);
- CounterGuard cntGuard(_waitCnt);
- while (_state != state) {
- guard.wait();
- }
-}
-
-
-void
-Actor::Run(FastOS_ThreadInterface *, void *)
-{
- while (!_exit) {
- {
- MonitorGuard guard(_cond);
- if (_queue.size() == 0) {
- setState(STATE_IDLE, guard);
- }
- }
- CmdList cmdList = _queue.dequeue();
- perform(1, 0, cmdList);
- }
- {
- MonitorGuard guard(_cond);
- setState(STATE_DONE, guard);
- }
-}
-
-} // namespace <unnamed>
-
-//-----------------------------------------------------------------------------
-
-void
-Test::testEmpty()
-{
- DL multicaster;
- multicast(multicaster);
- multicast_clear(multicaster);
- DL::Snapshot empty_snap(multicaster);
- EXPECT_TRUE(!empty_snap.valid());
-}
-
-
-void
-Test::testAdd()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- // ensure correct initial state
- EXPECT_TRUE(h1.getNum() == 0);
- EXPECT_TRUE(h2.getNum() == 0);
- EXPECT_TRUE(h3.getNum() == 0);
- EXPECT_TRUE(h4.getNum() == 0);
- EXPECT_TRUE(h5.getNum() == 0);
-
- // test basic adding
- multicaster.add(&h1);
- multicast(multicaster);
- multicaster.add(&h2);
- multicast(multicaster);
- multicaster.add(&h3);
- multicast(multicaster);
- multicaster.add(&h4);
- multicast(multicaster);
- multicaster.add(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 5);
- EXPECT_TRUE(h2.getNum() == 4);
- EXPECT_TRUE(h3.getNum() == 3);
- EXPECT_TRUE(h4.getNum() == 2);
- EXPECT_TRUE(h5.getNum() == 1);
-
- // duplicate adds
- multicaster.add(&h1);
- multicaster.add(&h1);
- multicaster.add(&h1);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 6);
- EXPECT_TRUE(h2.getNum() == 5);
- EXPECT_TRUE(h3.getNum() == 4);
- EXPECT_TRUE(h4.getNum() == 3);
- EXPECT_TRUE(h5.getNum() == 2);
-}
-
-
-void
-Test::testRemove()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 1);
- EXPECT_TRUE(h2.getNum() == 1);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 1);
- EXPECT_TRUE(h5.getNum() == 1);
-
- // remove middle
- multicaster.remove(&h3);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 2);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 2);
- EXPECT_TRUE(h5.getNum() == 2);
-
- // remove head
- multicaster.remove(&h1);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 3);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 3);
- EXPECT_TRUE(h5.getNum() == 3);
-
- // remove tail
- multicaster.remove(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 4);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 4);
- EXPECT_TRUE(h5.getNum() == 3);
-
- // duplicate removes
- multicaster.remove(&h1).remove(&h3).remove(&h5);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 5);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 5);
- EXPECT_TRUE(h5.getNum() == 3);
-
- // remove all
- multicaster.clear();
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 5);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 5);
- EXPECT_TRUE(h5.getNum() == 3);
-}
-
-
-void
-Test::testOneShot()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- // oneshot multicast removes handlers
- multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5);
- multicast_clear(multicaster);
- multicast(multicaster);
- EXPECT_TRUE(h1.getNum() == 1);
- EXPECT_TRUE(h2.getNum() == 1);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 1);
- EXPECT_TRUE(h5.getNum() == 1);
-}
-
-
-void
-Test::testMultiSnapshot()
-{
- DL multicaster;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
-
- DL::Snapshot empty_snap(multicaster);
- multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5);
- DL::Snapshot snap1(multicaster);
- multicaster.remove(&h3);
- DL::Snapshot snap2(multicaster);
- multicaster.remove(&h1);
- DL::Snapshot snap3(multicaster);
- multicaster.remove(&h5);
- DL::Snapshot snap4(multicaster);
-
- EXPECT_TRUE(!empty_snap.valid());
- for (; snap1.valid(); snap1.next()) {
- snap1.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 1);
- EXPECT_TRUE(h2.getNum() == 1);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 1);
- EXPECT_TRUE(h5.getNum() == 1);
- for (; snap2.valid(); snap2.next()) {
- snap2.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 2);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 2);
- EXPECT_TRUE(h5.getNum() == 2);
- for (; snap3.valid(); snap3.next()) {
- snap3.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 3);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 3);
- EXPECT_TRUE(h5.getNum() == 3);
- for (; snap4.valid(); snap4.next()) {
- snap4.get()->add();
- }
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 4);
- EXPECT_TRUE(h3.getNum() == 1);
- EXPECT_TRUE(h4.getNum() == 4);
- EXPECT_TRUE(h5.getNum() == 3);
-}
-
-
-void
-Test::testActors()
-{
- FastOS_ThreadPool pool(65000);
- History hist;
- Actor a1(1, &hist);
- Actor a2(2, &hist);
- DL dl;
- Handler h1;
- Handler h2;
-
- ASSERT_TRUE(pool.NewThread(&a1, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a2, 0) != 0);
-
- {
- CmdList prog;
- prog.push_back(cmd_add(&dl, &h1));
- prog.push_back(cmd_multicast(&dl));
- prog.push_back(cmd_add(&dl, &h2));
- prog.push_back(cmd_multicast(&dl));
- a1.doIt(prog);
- a1.waitState(Actor::STATE_IDLE);
- }
-
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 1);
-
- {
- CmdList prog;
- prog.push_back(cmd_remove(&dl, &h1));
- prog.push_back(cmd_multicast(&dl));
- prog.push_back(cmd_clear(&dl));
- prog.push_back(cmd_multicast(&dl));
- a2.doIt(prog);
- a2.waitState(Actor::STATE_IDLE);
- }
-
- EXPECT_TRUE(h1.getNum() == 2);
- EXPECT_TRUE(h2.getNum() == 2);
-
- {
- CmdList prog;
- prog.push_back(cmd_add(&dl, &h1));
- prog.push_back(cmd_add(&dl, &h2));
- prog.push_back(cmd_multicast_clear(&dl));
- prog.push_back(cmd_multicast(&dl));
- a1.doIt(prog);
- a1.waitState(Actor::STATE_IDLE);
- }
-
- EXPECT_TRUE(h1.getNum() == 3);
- EXPECT_TRUE(h2.getNum() == 3);
-
- {
- CmdList prog;
- prog.push_back(cmd_add(&dl, &h1));
- prog.push_back(cmd_add(&dl, &h2));
- prog.push_back(cmd_do(10));
- prog.push_back(cmd_do(10));
- prog.push_back(cmd_multicast(&dl));
- prog.push_back(cmd_done());
- prog.push_back(cmd_done());
- prog.push_back(cmd_exit());
- a2.doIt(prog);
- a2.waitState(Actor::STATE_DONE);
- }
-
- EXPECT_TRUE(h1.getNum() == 103);
- EXPECT_TRUE(h2.getNum() == 103);
-
- EXPECT_TRUE(hist.list.size() == 114);
-
- EXPECT_TRUE(hist.list[0].first == cmd_add(&dl, &h1));
- EXPECT_TRUE(hist.list[1].first == cmd_multicast(&dl));
- EXPECT_TRUE(hist.list[2].first == cmd_add(&dl, &h2));
- EXPECT_TRUE(hist.list[3].first == cmd_multicast(&dl));
- for (int i = 0; i < 4; i++) {
- EXPECT_TRUE(hist.list[i].second == 1);
- }
-
- EXPECT_TRUE(hist.list[4].first == cmd_remove(&dl, &h1));
- EXPECT_TRUE(hist.list[5].first == cmd_multicast(&dl));
- EXPECT_TRUE(hist.list[6].first == cmd_clear(&dl));
- EXPECT_TRUE(hist.list[7].first == cmd_multicast(&dl));
- for (int i = 4; i < 8; i++) {
- EXPECT_TRUE(hist.list[i].second == 2);
- }
-
- EXPECT_TRUE(hist.list[8].first == cmd_add(&dl, &h1));
- EXPECT_TRUE(hist.list[9].first == cmd_add(&dl, &h2));
- EXPECT_TRUE(hist.list[10].first == cmd_multicast_clear(&dl));
- EXPECT_TRUE(hist.list[11].first == cmd_multicast(&dl));
- for (int i = 8; i < 12; i++) {
- EXPECT_TRUE(hist.list[i].second == 1);
- }
-
- EXPECT_TRUE(hist.list[12].first == cmd_add(&dl, &h1));
- EXPECT_TRUE(hist.list[13].first == cmd_add(&dl, &h2));
- EXPECT_TRUE(hist.list[12].second == 2);
- EXPECT_TRUE(hist.list[13].second == 2);
-
- for (int i = 14; i < 114; i++) {
- EXPECT_TRUE(hist.list[i].first == cmd_multicast(&dl));
- EXPECT_TRUE(hist.list[i].second == 2);
- }
-
- a1.doIt(cmd_exit());
- a1.waitState(Actor::STATE_DONE);
-
- EXPECT_TRUE(a1.getOpCnt() == 8);
- EXPECT_TRUE(a2.getOpCnt() == 106);
-}
-
-
-void
-Test::stressTest()
-{
- FastOS_ThreadPool pool(65000);
- Actor a1(1, 0);
- Actor a2(2, 0);
- Actor a3(3, 0);
- Actor a4(4, 0);
- Actor a5(5, 0);
- Actor a6(6, 0);
- DL dl;
- Handler h1;
- Handler h2;
- Handler h3;
- Handler h4;
- Handler h5;
- int scale = 10000;
-
- ASSERT_TRUE(pool.NewThread(&a1, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a2, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a3, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a4, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a5, 0) != 0);
- ASSERT_TRUE(pool.NewThread(&a6, 0) != 0);
-
- CmdList prog_multicast;
- prog_multicast.push_back(cmd_do(10 * scale));
- prog_multicast.push_back(cmd_multicast(&dl));
- prog_multicast.push_back(cmd_done());
- prog_multicast.push_back(cmd_exit());
-
- CmdList prog_wait_snap;
- prog_wait_snap.push_back(cmd_do(10 * scale));
- prog_wait_snap.push_back(cmd_wait_snap(&dl));
- prog_wait_snap.push_back(cmd_done());
- prog_wait_snap.push_back(cmd_exit());
-
- CmdList prog_add_remove_1;
- prog_add_remove_1.push_back(cmd_do(scale));
- prog_add_remove_1.push_back(cmd_add(&dl, &h1));
- prog_add_remove_1.push_back(cmd_add(&dl, &h3));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h2));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h4));
- prog_add_remove_1.push_back(cmd_add(&dl, &h4));
- prog_add_remove_1.push_back(cmd_add(&dl, &h2));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h5));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h3));
- prog_add_remove_1.push_back(cmd_add(&dl, &h5));
- prog_add_remove_1.push_back(cmd_remove(&dl, &h1));
- prog_add_remove_1.push_back(cmd_done());
- prog_add_remove_1.push_back(cmd_exit());
-
- CmdList prog_add_remove_2;
- prog_add_remove_2.push_back(cmd_do(scale));
- prog_add_remove_2.push_back(cmd_add(&dl, &h5));
- prog_add_remove_2.push_back(cmd_add(&dl, &h4));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h1));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h3));
- prog_add_remove_2.push_back(cmd_add(&dl, &h1));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h2));
- prog_add_remove_2.push_back(cmd_add(&dl, &h2));
- prog_add_remove_2.push_back(cmd_add(&dl, &h3));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h5));
- prog_add_remove_2.push_back(cmd_remove(&dl, &h4));
- prog_add_remove_2.push_back(cmd_done());
- prog_add_remove_2.push_back(cmd_exit());
-
- CmdList prog_add_remove_3;
- prog_add_remove_3.push_back(cmd_do(scale));
- prog_add_remove_3.push_back(cmd_add(&dl, &h3));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h4));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h3));
- prog_add_remove_3.push_back(cmd_add(&dl, &h5));
- prog_add_remove_3.push_back(cmd_add(&dl, &h2));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h2));
- prog_add_remove_3.push_back(cmd_add(&dl, &h1));
- prog_add_remove_3.push_back(cmd_add(&dl, &h4));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h1));
- prog_add_remove_3.push_back(cmd_remove(&dl, &h5));
- prog_add_remove_3.push_back(cmd_done());
- prog_add_remove_3.push_back(cmd_exit());
-
- a1.doIt(prog_multicast);
- a2.doIt(prog_multicast);
- a3.doIt(prog_wait_snap);
- a4.doIt(prog_add_remove_1);
- a5.doIt(prog_add_remove_2);
- a6.doIt(prog_add_remove_3);
-
- a1.waitState(Actor::STATE_DONE);
- a2.waitState(Actor::STATE_DONE);
- a3.waitState(Actor::STATE_DONE);
- a4.waitState(Actor::STATE_DONE);
- a5.waitState(Actor::STATE_DONE);
- a6.waitState(Actor::STATE_DONE);
-
- EXPECT_TRUE(a1.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a2.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a3.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a4.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a5.getOpCnt() == 10 * scale);
- EXPECT_TRUE(a6.getOpCnt() == 10 * scale);
-}
-
-
-void
-Test::testWaitSnapshots()
-{
- FastOS_ThreadPool pool(65000);
- Actor a1(1, 0);
- DL dl;
- std::unique_ptr<DL::Snapshot> s1;
- std::unique_ptr<DL::Snapshot> s2;
- ASSERT_TRUE(pool.NewThread(&a1, 0) != 0);
- s1.reset(new DL::Snapshot(dl)); // create snap 1
- a1.doIt(cmd_wait_snap(&dl)); // wait for snaps
- std::this_thread::sleep_for(1s);
- EXPECT_TRUE(a1.getState() == Actor::STATE_BUSY); // still waiting...
- s2.reset(new DL::Snapshot(dl)); // create snap 2
- s1.reset(); // destroy snap 1
- std::this_thread::sleep_for(1s);
- EXPECT_TRUE(a1.getState() == Actor::STATE_IDLE); // wait done!
- a1.doIt(cmd_exit());
- a1.waitState(Actor::STATE_DONE);
- s2.reset(); // destroy snap 2
- EXPECT_TRUE(a1.getOpCnt() == 1);
-}
-
-//-----------------------------------------------------------------------------
-
-struct Foo { void completeBarrier() {} };
-
-int
-Test::Main()
-{
- TEST_INIT("delegatelist_test");
- LOG(info, "Lock size: %4zu bytes", sizeof(Lock));
- LOG(info, "ArrayQueue size: %4zu bytes", sizeof(ArrayQueue<Foo>));
- LOG(info, "std::vector size: %4zu bytes", sizeof(std::vector<Foo>));
- LOG(info, "EventBarrier size: %4zu bytes", sizeof(EventBarrier<Foo>));
- LOG(info, "DelegateList size: %4zu bytes", sizeof(DelegateList<Foo>));
-
- testEmpty();
- testAdd();
- testRemove();
- testOneShot();
- testMultiSnapshot();
-
- TEST_FLUSH();
- testActors();
- testWaitSnapshots();
-
- TEST_FLUSH();
- stressTest();
- TEST_DONE();
-}
-
-TEST_APPHOOK(Test);
diff --git a/vespalib/src/tests/rwlock/.gitignore b/vespalib/src/tests/rwlock/.gitignore
deleted file mode 100644
index 3ba74c11b14..00000000000
--- a/vespalib/src/tests/rwlock/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.depend
-Makefile
-rwlock_test
-vespalib_rwlock_test_app
diff --git a/vespalib/src/tests/rwlock/CMakeLists.txt b/vespalib/src/tests/rwlock/CMakeLists.txt
deleted file mode 100644
index 2eda95a200c..00000000000
--- a/vespalib/src/tests/rwlock/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(vespalib_rwlock_test_app TEST
- SOURCES
- rwlock_test.cpp
- DEPENDS
- vespalib
-)
-vespa_add_test(NAME vespalib_rwlock_test_app COMMAND vespalib_rwlock_test_app)
diff --git a/vespalib/src/tests/rwlock/rwlock_test.cpp b/vespalib/src/tests/rwlock/rwlock_test.cpp
deleted file mode 100644
index 66e73c3a5d9..00000000000
--- a/vespalib/src/tests/rwlock/rwlock_test.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include <vespa/vespalib/testkit/testapp.h>
-#include <vespa/vespalib/util/rwlock.h>
-
-using namespace vespalib;
-
-class RWLockTest : public TestApp
-{
-public:
- int Main() override;
- static RWLockReader rbvReader(RWLock & lock) { RWLockReader r(lock); return r; }
- static RWLockWriter rbvWriter(RWLock & lock) { RWLockWriter r(lock); return r; }
-};
-
-
-int
-RWLockTest::Main()
-{
- TEST_INIT("rwlock_test");
-
- RWLock lock;
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- EXPECT_TRUE(lock._givenLocks == 0);
- RWLockReader r1(lock);
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader r2(lock);
- EXPECT_TRUE(lock._givenLocks == 2);
- RWLockReader r3(lock);
- EXPECT_TRUE(lock._givenLocks == 3);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- EXPECT_TRUE(lock._givenLocks == 0);
- RWLockWriter w(lock);
- EXPECT_TRUE(lock._givenLocks == -1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- RWLockReader rbv(rbvReader(lock));
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader copy(rbv);
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader copy2(copy);
- EXPECT_TRUE(lock._givenLocks == 1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- RWLock lock2;
- RWLockReader copy(rbvReader(lock));
- EXPECT_TRUE(lock._givenLocks == 1);
- RWLockReader copy2(rbvReader(lock2));
- EXPECT_TRUE(lock._givenLocks == 1);
- EXPECT_TRUE(lock2._givenLocks == 1);
- RWLockReader rbv(rbvReader(lock));
- EXPECT_TRUE(lock._givenLocks == 2);
- copy=rbv;
- EXPECT_TRUE(lock._givenLocks == 1);
- copy2=copy;
- EXPECT_TRUE(lock2._givenLocks == 0);
- EXPECT_TRUE(lock._givenLocks == 1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
- {
- RWLockWriter rbv(rbvWriter(lock));
- EXPECT_TRUE(lock._givenLocks == -1);
- RWLockWriter copy(rbv);
- EXPECT_TRUE(lock._givenLocks == -1);
- RWLockWriter copy2(copy);
- EXPECT_TRUE(lock._givenLocks == -1);
- }
- EXPECT_TRUE(lock._givenLocks == 0);
-
- TEST_DONE();
-}
-
-TEST_APPHOOK(RWLockTest)
diff --git a/vespalib/src/tests/sync/sync_test.cpp b/vespalib/src/tests/sync/sync_test.cpp
index c8888bc8e54..0925ce060a0 100644
--- a/vespalib/src/tests/sync/sync_test.cpp
+++ b/vespalib/src/tests/sync/sync_test.cpp
@@ -3,6 +3,44 @@
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/vespalib/util/sync.h>
+namespace vespalib {
+class TryLock
+{
+private:
+ friend class LockGuard;
+ friend class MonitorGuard;
+
+ std::unique_lock<std::mutex> _guard;
+ std::condition_variable *_cond;
+
+public:
+ TryLock(const Lock &lock)
+ : _guard(*lock._mutex, std::try_to_lock), _cond(nullptr)
+ {}
+ TryLock(const Monitor &mon)
+ : _guard(*mon._mutex, std::try_to_lock),
+ _cond(_guard ? mon._cond.get() : nullptr)
+ {}
+ ~TryLock() = default;
+
+ TryLock(const TryLock &) = delete;
+ TryLock &operator=(const TryLock &) = delete;
+
+ /**
+ * @brief Check whether this object holds a lock
+ *
+ * @return true if this object holds a lock
+ **/
+ bool hasLock() const { return static_cast<bool>(_guard); }
+ void unlock() {
+ if (_guard) {
+ _guard.unlock();
+ _cond = nullptr;
+ }
+ }
+};
+
+}
using namespace vespalib;
#define CHECK_LOCKED(m) { TryLock tl(m); EXPECT_TRUE(!tl.hasLock()); }
@@ -18,7 +56,7 @@ private:
LockGuard lockMonitor() { return LockGuard(_monitor); }
MonitorGuard obtainMonitor() { return MonitorGuard(_monitor); }
public:
- ~Test();
+ ~Test() override;
void testCountDownLatch();
int Main() override;
};
@@ -139,97 +177,6 @@ Test::Main()
MonitorGuard guard(monitor);
CHECK_LOCKED(monitor);
}
- // TryLock hands the lock over to a LockGuard/MonitorGuard
- {
- Lock lock;
- CHECK_UNLOCKED(lock);
- TryLock a(lock);
- CHECK_LOCKED(lock);
- if (a.hasLock()) {
- LockGuard guard(std::move(a));
- CHECK_LOCKED(lock);
- }
- CHECK_UNLOCKED(lock);
- }
- {
- Monitor mon;
- CHECK_UNLOCKED(mon);
- TryLock a(mon);
- CHECK_LOCKED(mon);
- if (a.hasLock()) {
- LockGuard guard(std::move(a));
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(mon);
- }
- {
- Monitor mon;
- CHECK_UNLOCKED(mon);
- TryLock a(mon);
- CHECK_LOCKED(mon);
- if (a.hasLock()) {
- MonitorGuard guard(std::move(a));
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(mon);
- }
- {
- Lock lock;
-
- CHECK_UNLOCKED(lock);
- TryLock a(lock);
- CHECK_LOCKED(lock);
- TryLock b(lock);
- CHECK_LOCKED(lock);
-
- EXPECT_TRUE(a.hasLock());
- EXPECT_TRUE(!b.hasLock());
- {
- CHECK_LOCKED(lock);
- EXPECT_TRUE(a.hasLock());
- LockGuard guard(std::move(a));
- EXPECT_TRUE(!a.hasLock());
- CHECK_LOCKED(lock);
- }
- CHECK_UNLOCKED(lock);
- }
- // TryLock will unlock when exiting scope if lock was not passed on
- {
- Lock lock;
- Monitor mon;
- CHECK_UNLOCKED(lock);
- CHECK_UNLOCKED(mon);
- {
- TryLock a(lock);
- EXPECT_TRUE(a.hasLock());
- TryLock b(mon);
- EXPECT_TRUE(b.hasLock());
- CHECK_LOCKED(lock);
- CHECK_LOCKED(mon);
- }
- CHECK_UNLOCKED(lock);
- CHECK_UNLOCKED(mon);
- }
- // TryLock explicitt unlock of lock
- {
- Lock lock;
- TryLock tl(lock);
- EXPECT_TRUE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- }
- // TryLock explicitt unlock of monitor
- {
- Monitor lock;
- TryLock tl(lock);
- EXPECT_TRUE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- tl.unlock();
- EXPECT_FALSE(tl.hasLock());
- }
// LockGuard/MonitorGuard have destructive move
{
Lock lock;
diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
index df1b68cff12..1f8c72a5a64 100644
--- a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
+++ b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp
@@ -5,8 +5,9 @@
namespace vespalib {
using alloc::Alloc;
+using LockGuard = std::lock_guard<std::mutex>;
-MemoryDataStore::MemoryDataStore(Alloc && initialAlloc, Lock * lock) :
+MemoryDataStore::MemoryDataStore(Alloc && initialAlloc, std::mutex * lock) :
_buffers(),
_writePos(0),
_lock(lock)
diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.h b/vespalib/src/vespa/vespalib/data/memorydatastore.h
index 2d02bfb107c..fa6113279da 100644
--- a/vespalib/src/vespa/vespalib/data/memorydatastore.h
+++ b/vespalib/src/vespa/vespalib/data/memorydatastore.h
@@ -3,8 +3,8 @@
#include <vespa/vespalib/util/alloc.h>
#include <vespa/vespalib/util/array.h>
-#include <vespa/vespalib/util/sync.h>
#include <vector>
+#include <mutex>
namespace vespalib {
@@ -24,7 +24,7 @@ public:
private:
void * _data;
};
- MemoryDataStore(alloc::Alloc && initialAlloc=alloc::Alloc::alloc(256), Lock * lock=nullptr);
+ MemoryDataStore(alloc::Alloc && initialAlloc=alloc::Alloc::alloc(256), std::mutex * lock=nullptr);
MemoryDataStore(const MemoryDataStore &) = delete;
MemoryDataStore & operator = (const MemoryDataStore &) = delete;
~MemoryDataStore();
@@ -41,7 +41,7 @@ public:
private:
std::vector<alloc::Alloc> _buffers;
size_t _writePos;
- Lock * _lock;
+ std::mutex * _lock;
};
class VariableSizeVector
diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.cpp b/vespalib/src/vespa/vespalib/testkit/test_master.cpp
index 4b673d0ee0d..60e51ac3a91 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_master.cpp
+++ b/vespalib/src/vespa/vespalib/testkit/test_master.cpp
@@ -37,7 +37,7 @@ __thread TestMaster::ThreadState *TestMaster::_threadState = 0;
TestMaster::TraceItem::~TraceItem() = default;
TestMaster::ThreadState &
-TestMaster::threadState(const vespalib::LockGuard &)
+TestMaster::threadState(const lock_guard &)
{
if (_threadState == 0) {
std::ostringstream threadName;
@@ -55,7 +55,7 @@ TestMaster::threadState()
return *_threadState;
}
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
return threadState(guard);
}
}
@@ -63,7 +63,7 @@ TestMaster::threadState()
//-----------------------------------------------------------------------------
void
-TestMaster::checkFailed(const vespalib::LockGuard &guard,
+TestMaster::checkFailed(const lock_guard &guard,
const char *file, uint32_t line, const char *str)
{
ThreadState &thread = threadState(guard);
@@ -81,7 +81,7 @@ TestMaster::checkFailed(const vespalib::LockGuard &guard,
}
void
-TestMaster::printDiff(const vespalib::LockGuard &guard,
+TestMaster::printDiff(const lock_guard &guard,
const std::string &text, const std::string &file, uint32_t line,
const std::string &lhs, const std::string &rhs)
{
@@ -106,7 +106,7 @@ TestMaster::printDiff(const vespalib::LockGuard &guard,
}
void
-TestMaster::handleFailure(const vespalib::LockGuard &guard, bool fatal)
+TestMaster::handleFailure(const lock_guard &guard, bool fatal)
{
ThreadState &thread = threadState(guard);
if (fatal) {
@@ -120,7 +120,7 @@ TestMaster::handleFailure(const vespalib::LockGuard &guard, bool fatal)
}
void
-TestMaster::closeDebugFiles(const vespalib::LockGuard &)
+TestMaster::closeDebugFiles(const lock_guard &)
{
if (_state.lhsFile != NULL) {
fclose(_state.lhsFile);
@@ -133,7 +133,7 @@ TestMaster::closeDebugFiles(const vespalib::LockGuard &)
}
void
-TestMaster::importThreads(const vespalib::LockGuard &)
+TestMaster::importThreads(const lock_guard &)
{
size_t importCnt = 0;
for (size_t i = 0; i < _threadStorage.size(); ++i) {
@@ -149,7 +149,7 @@ TestMaster::importThreads(const vespalib::LockGuard &)
}
bool
-TestMaster::reportConclusion(const vespalib::LockGuard &)
+TestMaster::reportConclusion(const lock_guard &)
{
bool ok = (_state.failCnt == 0);
fprintf(stderr, "%s: info: summary --- %zu check(s) passed --- %zu check(s) failed\n",
@@ -175,7 +175,7 @@ TestMaster::TestMaster()
void
TestMaster::init(const char *name)
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
_name = skip_path(name);
fprintf(stderr, "%s: info: running test suite '%s'\n", _name.c_str(), _name.c_str());
}
@@ -183,7 +183,7 @@ TestMaster::init(const char *name)
std::string
TestMaster::getName()
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
return _name;
}
@@ -226,7 +226,7 @@ TestMaster::setThreadIgnore(bool ignore)
size_t revertCnt = (thread.failCnt - thread.preIgnoreFailCnt);
thread.failCnt = thread.preIgnoreFailCnt;
if (revertCnt > 0) {
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
assert(_state.failCnt >= revertCnt);
_state.failCnt -= revertCnt;
}
@@ -272,7 +272,7 @@ TestMaster::getThreadFailCnt()
TestMaster::Progress
TestMaster::getProgress()
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
return Progress(_state.passCnt, _state.failCnt);
}
@@ -280,7 +280,7 @@ void
TestMaster::openDebugFiles(const std::string &lhsFile,
const std::string &rhsFile)
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
closeDebugFiles(guard);
_state.lhsFile = fopen(lhsFile.c_str(), "w");
_state.rhsFile = fopen(rhsFile.c_str(), "w");
@@ -318,7 +318,7 @@ TestMaster::check(bool rc, const char *file, uint32_t line,
return true;
}
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
checkFailed(guard, file, line, str);
handleFailure(guard, fatal);
}
@@ -330,7 +330,7 @@ TestMaster::flush(const char *file, uint32_t line)
{
ThreadState &thread = threadState();
if (thread.passCnt > 0) {
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
_state.passCnt += thread.passCnt;
fprintf(stderr, "%s: info: flushed %zu passed check(s) from thread '%s' (%s:%d)\n",
_name.c_str(), thread.passCnt, thread.name.c_str(), skip_path(file), line);
@@ -349,7 +349,7 @@ TestMaster::trace(const char *file, uint32_t line)
bool
TestMaster::discardFailedChecks(size_t failCnt)
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
ThreadState &thread = threadState(guard);
if (failCnt == _state.failCnt) {
fprintf(stderr, "%s: info: discarding %zu failed check(s)\n", _name.c_str(), _state.failCnt);
@@ -367,7 +367,7 @@ TestMaster::discardFailedChecks(size_t failCnt)
bool
TestMaster::fini()
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
closeDebugFiles(guard);
importThreads(guard);
return reportConclusion(guard);
diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.h b/vespalib/src/vespa/vespalib/testkit/test_master.h
index a9dc5ebb3a2..c20982b994d 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_master.h
+++ b/vespalib/src/vespa/vespalib/testkit/test_master.h
@@ -2,10 +2,10 @@
#pragma once
-#include <vespa/vespalib/util/sync.h>
#include <string>
#include <vector>
#include <memory>
+#include <mutex>
namespace vespalib {
@@ -69,24 +69,25 @@ private:
};
private:
- vespalib::Lock _lock;
+ std::mutex _lock;
std::string _name;
std::string _path_prefix;
SharedState _state;
std::vector<std::unique_ptr<ThreadState> > _threadStorage;
+ using lock_guard = std::lock_guard<std::mutex>;
private:
- ThreadState &threadState(const vespalib::LockGuard &);
+ ThreadState &threadState(const lock_guard &);
ThreadState &threadState();
- void checkFailed(const vespalib::LockGuard &,
+ void checkFailed(const lock_guard &,
const char *file, uint32_t line, const char *str);
- void printDiff(const vespalib::LockGuard &,
+ void printDiff(const lock_guard &,
const std::string &text, const std::string &file, uint32_t line,
const std::string &lhs, const std::string &rhs);
- void handleFailure(const vespalib::LockGuard &, bool do_abort);
- void closeDebugFiles(const vespalib::LockGuard &);
- void importThreads(const vespalib::LockGuard &);
- bool reportConclusion(const vespalib::LockGuard &);
+ void handleFailure(const lock_guard &, bool do_abort);
+ void closeDebugFiles(const lock_guard &);
+ void importThreads(const lock_guard &);
+ bool reportConclusion(const lock_guard &);
private:
TestMaster();
diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.hpp b/vespalib/src/vespa/vespalib/testkit/test_master.hpp
index f165458c9aa..245c128b788 100644
--- a/vespalib/src/vespa/vespalib/testkit/test_master.hpp
+++ b/vespalib/src/vespa/vespalib/testkit/test_master.hpp
@@ -33,7 +33,7 @@ TestMaster::compare(const char *file, uint32_t line,
lhs << a;
rhs << b;
{
- vespalib::LockGuard guard(_lock);
+ lock_guard guard(_lock);
checkFailed(guard, file, line, str.c_str());
printDiff(guard, str, file, line, lhs.str(), rhs.str());
handleFailure(guard, fatal);
diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
index fd645f9008c..ea2189fc3a8 100644
--- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -40,7 +40,6 @@ vespa_add_library(vespalib_vespalib_util OBJECT
reusable_set_pool.cpp
runnable.cpp
runnable_pair.cpp
- rwlock.cpp
sequence.cpp
sha1.cpp
sig_catch.cpp
diff --git a/vespalib/src/vespa/vespalib/util/alloc.cpp b/vespalib/src/vespa/vespalib/util/alloc.cpp
index 5ae499f5482..745fb50db03 100644
--- a/vespalib/src/vespa/vespalib/util/alloc.cpp
+++ b/vespalib/src/vespa/vespalib/util/alloc.cpp
@@ -4,11 +4,11 @@
#include <vespa/vespalib/util/stringfmt.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/util/backtrace.h>
-#include <vespa/vespalib/util/sync.h>
#include <map>
#include <atomic>
#include <unordered_map>
#include <cassert>
+#include <mutex>
#include <vespa/fastos/file.h>
#include <unistd.h>
@@ -25,7 +25,7 @@ int _G_HugeFlags = 0;
const size_t _G_pageSize = getpagesize();
size_t _G_MMapLogLimit = std::numeric_limits<size_t>::max();
size_t _G_MMapNoCoreLimit = std::numeric_limits<size_t>::max();
-Lock _G_lock;
+std::mutex _G_lock;
std::atomic<size_t> _G_mmapCount(0);
size_t
@@ -362,7 +362,7 @@ MMapAllocator::salloc(size_t sz, void * wantedAddress)
}
#endif
if (sz >= _G_MMapLogLimit) {
- LockGuard guard(_G_lock);
+ std::lock_guard guard(_G_lock);
_G_HugeMappings[buf] = MMapInfo(mmapId, sz, stackTrace);
LOG(info, "%ld mappings of accumulated size %ld", _G_HugeMappings.size(), sum(_G_HugeMappings));
}
@@ -412,7 +412,7 @@ void MMapAllocator::sfree(PtrAndSize alloc)
retval = munmap(alloc.first, alloc.second);
assert(retval == 0);
if (alloc.second >= _G_MMapLogLimit) {
- LockGuard guard(_G_lock);
+ std::lock_guard guard(_G_lock);
MMapInfo info = _G_HugeMappings[alloc.first];
assert(alloc.second == info._sz);
_G_HugeMappings.erase(alloc.first);
diff --git a/vespalib/src/vespa/vespalib/util/delegatelist.hpp b/vespalib/src/vespa/vespalib/util/delegatelist.hpp
deleted file mode 100644
index 716474f66f7..00000000000
--- a/vespalib/src/vespa/vespalib/util/delegatelist.hpp
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include "eventbarrier.hpp"
-#include "sync.h"
-
-namespace vespalib {
-
-/**
- * Data structure for robust event multi-casting in a multi-threaded
- * environment. The state tracked by this class can be modeled as a
- * set of bald object pointers; the delegates. All interaction with
- * the delegates is done through a snapshot of the delegate list. The
- * list may be modified at any time. Modifications will not be visible
- * to already existing snapshots. A separate method may be used to
- * wait for the destruction of all currently active snapshots. This
- * synchronization will ensure visibility of any previous
- * modifications to the delegate list. State snapshotting is
- * implemented with reference counted immutable lists. Snapshot
- * waiting is implemented using event barriers.
- **/
-template <typename T>
-class DelegateList
-{
-private:
- /**
- * Simple class used to synchronize with the completion of an
- * event barrier by coupling barrier completion to a gate.
- **/
- struct Sync
- {
- Gate gate;
- Sync() : gate() {}
- void completeBarrier() { gate.countDown(); }
- };
-
- /**
- * Inner structure used when keeping track of a set of delegates.
- **/
- struct Node {
- uint32_t refcnt; // the number of incoming pointers to this node.
- T *delegate; // the delegate tracked by this node.
- Node *next; // the next node in this list.
- };
-
- Lock _lock; // lock protecting access to this object
- Node *_head; // head of current list of delegates
- EventBarrier<Sync> _barrier; // object used to resolve event barriers
- Node *_freeNodes; // a list of recyclable internal nodes
- int _activeNodes; // number of internal nodes currently in use
- ArrayQueue<T*> _stack; // explicit stack for cheap 'recursion'
-
- /**
- * Allocate a new node and initialize it with the given data
- * members. Nodes are recycled internally by this object to reduce
- * overhead.
- *
- * @return the new node
- * @param delegate the delegate for the new node
- * @param next the next pointer for the new node
- **/
- Node *allocNode(T *delegate, Node *next) {
- Node *node = _freeNodes;
- if (node != 0) {
- _freeNodes = node->next;
- } else {
- node = new Node();
- }
- node->refcnt = 1;
- node->delegate = delegate;
- node->next = next;
- ++_activeNodes;
- return node;
- }
-
- /**
- * Copy a list of nodes. This will increase the reference count of
- * the list.
- *
- * @return the copy of the list
- * @param list the list to copy
- **/
- Node *copyList(Node *list) {
- if (list != 0) {
- ++list->refcnt;
- }
- return list;
- }
-
- /**
- * Free a list of nodes. This will decrease the reference count of
- * the list. Any nodes no longer in use will be put back on the
- * internal free list.
- *
- * @return 0
- * @param list the list to free
- **/
- Node *freeList(Node *list) {
- while (list != 0 && --list->refcnt == 0) {
- Node *node = list;
- list = node->next;
- node->next = _freeNodes;
- _freeNodes = node;
- --_activeNodes;
- }
- return 0;
- }
-
- DelegateList(const DelegateList &);
- DelegateList &operator=(const DelegateList &);
-
-public:
- /**
- * A snapshot of a delegate list. The only way to access the
- * delegates kept by a delegate list is to create a snapshot of
- * it. The snapshot lets the user traverse the list of delegates,
- * accessing each of them in turn. The existence of a snapshot is
- * used by the delegate list to identify that someone is observing
- * the delegate list in a specific state. Snapshots should be
- * created on the stack in a scope as close as possible to the
- * code actually accessing the delegates. The delegate list itself
- * may not be destructed until all snapshots of that list have
- * been destructed.
- **/
- class Snapshot
- {
- private:
- DelegateList &_list; // the parent object
- Node *_head; // head of the snapshotted list
- Node *_node; // current position within snapshot
- uint32_t _token; // token used for barrier resolving
-
- Snapshot(const Snapshot &);
- Snapshot &operator=(const Snapshot &);
- public:
- /**
- * Create a snapshot of the given delegate list. The snapshots
- * current position will be set to the first delegate part of
- * the snapshot.
- *
- * @param list the delegate list we are snapshotting
- **/
- explicit Snapshot(DelegateList &list) : _list(list) {
- LockGuard guard(list._lock);
- _head = list.copyList(list._head);
- _node = _head;
- _token = list._barrier.startEvent();
- }
-
- /**
- * Destructing a snapshot will tell the delegate list that we
- * are no longer accessing the list in the state observed by
- * the snapshot.
- **/
- ~Snapshot() {
- LockGuard guard(_list._lock);
- _list.freeList(_head);
- _list._barrier.completeEvent(_token);
- }
-
- /**
- * Check whether the current delegate is valid. A snapshot
- * becomes invalid after the user has stepped through all
- * delegates part of the snapshot using the 'next' method.
- *
- * @return true if the current delegate is valid
- **/
- bool valid() const {
- return (_node != 0);
- }
-
- /**
- * Step to the next delegate. This method may only be called
- * if the 'valid' method returns true.
- **/
- void next() {
- _node = _node->next;
- }
-
- /**
- * Get the current delegate. This method may only be called if
- * the 'valid' method returns true.
- *
- * @return current delegate
- **/
- T *get() const {
- return _node->delegate;
- }
- };
-
- /**
- * Create an initially empty delegate list.
- **/
- DelegateList()
- : _lock(),
- _head(0),
- _barrier(),
- _freeNodes(0),
- _activeNodes(0),
- _stack()
- {
- }
-
- /**
- * The destructor will clean up internal memory usage. The
- * delegate list itself does not need to be empty when it is
- * deleted. However, there may be no active snapshots of it and
- * no-one may be waiting for snapshot destruction.
- **/
- ~DelegateList() {
- freeList(_head);
- assert(_barrier.countBarriers() == 0);
- assert(_barrier.countEvents() == 0);
- assert(_activeNodes == 0);
- while (_freeNodes != 0) {
- Node *node = _freeNodes;
- _freeNodes = node->next;
- delete node;
- }
- }
-
- /**
- * Add a delegate to this list. Adding a delegate that is already
- * in the list will have no effect.
- *
- * @return this object, for chaining
- * @param delegate the delegate to add
- **/
- DelegateList &add(T *delegate) {
- LockGuard guard(_lock);
- Node *node = _head;
- while (node != 0 && node->delegate != delegate) {
- node = node->next;
- }
- if (node == 0) {
- _head = allocNode(delegate, _head);
- }
- return *this;
- }
-
- /**
- * Remove a delegate from this list.
- *
- * @return this object, for chaining
- * @param delegate the delegate to remove
- **/
- DelegateList &remove(T *delegate) {
- LockGuard guard(_lock);
- _stack.clear();
- Node *node = _head;
- while (node != 0 && node->delegate != delegate) {
- _stack.push(node->delegate);
- node = node->next;
- }
- if (node != 0) { // delegate found in list
- node = copyList(node->next);
- while (!_stack.empty()) {
- try {
- node = allocNode(_stack.back(), node);
- } catch (...) {
- freeList(node);
- throw;
- }
- _stack.popBack();
- }
- freeList(_head);
- _head = node;
- }
- return *this;
- }
-
- /**
- * Remove all delegates currently in this list.
- *
- * @return this object, for chaining
- **/
- DelegateList &clear() {
- LockGuard guard(_lock);
- _head = freeList(_head);
- return *this;
- }
-
- /**
- * Wait for the destruction of all currently active snapshots of
- * this list. This method will block until all relevant snapshots
- * are destructed. The creation of new snapshots will not
- * interfere with the completion of this method. This method is
- * used to enforce visibility between threads; after this method
- * returns, any modifications performed on the list before this
- * method was invoked will be visible to all threads.
- *
- * @return this object, for chaining
- **/
- DelegateList &waitSnapshots() {
- Sync sync;
- {
- LockGuard guard(_lock);
- if (!_barrier.startBarrier(sync)) {
- return *this;
- }
- }
- sync.gate.await();
- return *this;
- }
-};
-
-} // namespace vespalib
-
diff --git a/vespalib/src/vespa/vespalib/util/ptrholder.h b/vespalib/src/vespa/vespalib/util/ptrholder.h
index 1c06e5c53e6..be528ba25db 100644
--- a/vespalib/src/vespa/vespalib/util/ptrholder.h
+++ b/vespalib/src/vespa/vespalib/util/ptrholder.h
@@ -4,7 +4,7 @@
#include <algorithm>
#include <memory>
-#include <vespa/vespalib/util/sync.h>
+#include <mutex>
namespace vespalib {
@@ -29,11 +29,11 @@ class PtrHolder
private:
std::shared_ptr<T> _current;
std::shared_ptr<T> _next;
- mutable Lock _lock;
-
- PtrHolder(const PtrHolder &);
- PtrHolder &operator=(const PtrHolder &);
+ mutable std::mutex _lock;
+ using LockGuard = std::lock_guard<std::mutex>;
public:
+ PtrHolder(const PtrHolder &) = delete;
+ PtrHolder &operator=(const PtrHolder &) = delete;
/**
* @brief Create an empty PtrHolder with both current and new
* pointers set to 0
@@ -53,14 +53,14 @@ public:
*
* @return true if the current value is set (not 0)
**/
- bool hasValue() const { return (_current.get() != nullptr); }
+ bool hasValue() const { return bool(_current); }
/**
* @brief Check if the new value is set (not 0)
*
* @return true if the new value is set (not 0)
**/
- bool hasNewValue() const { return (_next.get() != nullptr); }
+ bool hasNewValue() const { return bool(_next); }
/**
* @brief Set a new value
diff --git a/vespalib/src/vespa/vespalib/util/rwlock.cpp b/vespalib/src/vespa/vespalib/util/rwlock.cpp
deleted file mode 100644
index fc3799bc1d0..00000000000
--- a/vespalib/src/vespa/vespalib/util/rwlock.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include "rwlock.h"
-#include <cassert>
-
-namespace vespalib {
-
-void RWLock::lockRead() {
- MonitorGuard guard(_monitor);
- CounterGuard waitCnt(_waitingReaders);
- while (_givenLocks == -1 || _waitingWriters > 0) {
- guard.wait();
- }
- ++_givenLocks;
-}
-
-void RWLock::unlockRead() {
- MonitorGuard guard(_monitor);
- assert(_givenLocks > 0);
- if (--_givenLocks == 0 && _waitingWriters > 0) {
- guard.broadcast();
- }
-}
-
-void RWLock::lockWrite() {
- MonitorGuard guard(_monitor);
- CounterGuard waitCnt(_waitingWriters);
- while (_givenLocks != 0) {
- guard.wait();
- }
- _givenLocks = -1;
-}
-
-void RWLock::unlockWrite() {
- MonitorGuard guard(_monitor);
- assert(_givenLocks == -1);
- _givenLocks = 0;
- if (_waitingReaders > 0 || _waitingWriters > 0) {
- guard.broadcast();
- }
-}
-
-RWLock *
-RWLockReader::stealLock() {
- RWLock * ret(_lock);
- assert(ret != nullptr);
- _lock = nullptr;
- return ret;
-}
-
-RWLock *
-RWLockWriter::stealLock() {
- RWLock * ret(_lock);
- assert(ret != nullptr);
- _lock = nullptr;
- return ret;
-}
-
-} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/util/rwlock.h b/vespalib/src/vespa/vespalib/util/rwlock.h
deleted file mode 100644
index 8818291ae6c..00000000000
--- a/vespalib/src/vespa/vespalib/util/rwlock.h
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#pragma once
-
-#include <vespa/vespalib/util/sync.h>
-#include <vespa/vespalib/util/guard.h>
-
-class RWLockTest;
-
-namespace vespalib {
-
-/**
- * @brief An RWLock is a reader/writer lock. It can either be held by
- * any number of readers or a single writer at any time.
- *
- * The RWLockReader and RWLockWriter classes are used to acquire and
- * release reader and writer locks respectively.
- *
- * Writer locks have priority above reader locks to prevent
- * starvation.
- **/
-class RWLock
-{
-private:
- friend class ::RWLockTest;
- friend class RWLockReader;
- friend class RWLockWriter;
-
- int _givenLocks;
- int _waitingReaders;
- int _waitingWriters;
- Monitor _monitor;
-
- void lockRead();
- void unlockRead();
- void lockWrite();
- void unlockWrite();
-public:
- /**
- * @brief Create a new RWLock
- **/
- RWLock()
- : _givenLocks(0),
- _waitingReaders(0),
- _waitingWriters(0),
- _monitor() {}
- /**
- * @brief Create a new RWLock, ignoring the right hand side.
- *
- * It makes no sense to copy the state of an RWLock, but we want
- * to allow copying objects that contain RWLock objects.
- *
- * @param rhs ignore this
- **/
- RWLock(const RWLock &rhs)
- : _givenLocks(0),
- _waitingReaders(0),
- _waitingWriters(0),
- _monitor() { (void) rhs;}
- /**
- * @brief Assignment operator ignoring the right hand side.
- *
- * It makes no sense to assign the state of one RWLock to another,
- * but we want to allow assigning objects that contain RWLock
- * objects.
- *
- * @param rhs ignore this
- **/
- RWLock &operator=(const RWLock &rhs) {
- (void) rhs;
- return *this;
- }
-
- /**
- * To get an instance of RWLockReader or RWLockWriter that isn't
- * associated with a specific RWLock at initialization, you may
- * construct them from this tag type.
- **/
- struct InitiallyUnlockedGuard {};
-};
-
-#ifndef IAM_DOXYGEN
-class RWLockReaderHandover
-{
-private:
- friend class RWLockReader;
- RWLock *_lock;
- RWLockReaderHandover(const RWLockReaderHandover &);
- RWLockReaderHandover &operator=(const RWLockReaderHandover &);
- RWLockReaderHandover(RWLock *m) : _lock(m) {}
-public:
-};
-
-class RWLockWriterHandover
-{
-private:
- friend class RWLockWriter;
- RWLock *_lock;
- RWLockWriterHandover(const RWLockWriterHandover &);
- RWLockWriterHandover &operator=(const RWLockWriterHandover &);
- RWLockWriterHandover(RWLock *m) : _lock(m) {}
-public:
-};
-#endif
-
-
-/**
- * @brief An RWLockReader holds a reader lock on an RWLock.
- *
- * The lock is acquired in the constructor and released in the
- * destructor.
- *
- * RWLockReader has destructive copy (like unique_ptr). Assigning from
- * or copying a RWLockReader has the semantic of transferring the lock
- * from one object to the other. Note that assigning from or copying
- * a RWLockReader that does not have a lock will result in an assert.
- **/
-class RWLockReader
-{
-private:
- RWLock * _lock;
- RWLock * stealLock();
- void cleanup() { if (_lock != nullptr) { _lock->unlockRead(); } }
-public:
-
- /**
- * @brief Obtain reader lock.
- *
- * This will block until a reader lock can be acquired.
- *
- * @param lock the underlying RWLock object
- **/
- RWLockReader(RWLock &lock) : _lock(&lock) { _lock->lockRead(); }
-
- /**
- * @brief Construct initially unlocked guard.
- * @param tag (unused) marker argument
- **/
- RWLockReader(const RWLock::InitiallyUnlockedGuard &tag) : _lock(nullptr) { (void)tag; }
-
- /**
- * @brief Steal the lock from the given RWLockReader
- *
- * @param rhs steal the lock from this one
- **/
- RWLockReader(RWLockReader &rhs) : _lock(rhs.stealLock()) {}
-
- /**
- * @brief Steal the lock from the given RWLockReader
- *
- * @param rhs steal the lock from this one
- **/
- RWLockReader &operator=(RWLockReader & rhs) {
- if (this != & rhs) {
- cleanup();
- _lock = rhs.stealLock();
- }
- return *this;
- }
-
- /**
- * @brief Release the lock obtained in the constructor
- **/
- ~RWLockReader() { cleanup(); }
-
-#ifndef IAM_DOXYGEN
- RWLockReader(const RWLockReaderHandover &rhs) : _lock(rhs._lock) {}
- operator RWLockReaderHandover() { return RWLockReaderHandover(stealLock()); }
-#endif
-};
-
-
-/**
- * @brief An RWLockWriter holds a writer lock on an RWLock.
- *
- * The lock is acquired in the constructor and released in the
- * destructor.
- *
- * RWLockWriter has destructive copy (like unique_ptr). Assigning from
- * or copying a RWLockWriter has the semantic of transferring the lock
- * from one object to the other, and assignment is similar. Note that
- * assigning from or copying a RWLockWriter that does not have a lock
- * will result in an assert.
- **/
-class RWLockWriter
-{
-private:
- RWLock * _lock;
- RWLock * stealLock();
- void cleanup() { if (_lock != nullptr) { _lock->unlockWrite(); } }
-public:
-
- /**
- * @brief Obtain writer lock.
- *
- * This will block until a writer lock can be acquired.
- *
- * @param lock the underlying RWLock object
- **/
- RWLockWriter(RWLock &lock) : _lock(&lock) { _lock->lockWrite(); }
-
- /**
- * @brief Construct initially unlocked guard.
- * @param tag (unused) marker argument
- **/
- RWLockWriter(const RWLock::InitiallyUnlockedGuard &tag) : _lock(nullptr) { (void)tag; }
-
- /**
- * @brief Steal the lock from the given RWLockWriter
- *
- * @param rhs steal the lock from this one
- **/
- RWLockWriter(RWLockWriter &rhs) : _lock(rhs.stealLock()) {}
-
- /**
- * @brief Steal the lock from the given RWLockWriter
- *
- * @param rhs steal the lock from this one
- **/
- RWLockWriter &operator=(RWLockWriter & rhs) {
- if (this != & rhs) {
- cleanup();
- _lock = rhs.stealLock();
- }
- return *this;
- }
-
- /**
- * @brief Release the lock obtained in the constructor
- **/
- ~RWLockWriter() { cleanup(); }
-
-#ifndef IAM_DOXYGEN
- RWLockWriter(const RWLockWriterHandover &rhs) : _lock(rhs._lock) {}
- operator RWLockWriterHandover() { return RWLockWriterHandover(stealLock()); }
-#endif
-};
-
-} // namespace vespalib
-
diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp
index 886003a2ab6..e0d78c5d1b7 100644
--- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp
+++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp
@@ -69,7 +69,7 @@ SimpleThreadBundle::UP
SimpleThreadBundle::Pool::obtain()
{
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
if (!_bundles.empty()) {
SimpleThreadBundle::UP ret(_bundles.back());
_bundles.pop_back();
@@ -82,7 +82,7 @@ SimpleThreadBundle::Pool::obtain()
void
SimpleThreadBundle::Pool::release(SimpleThreadBundle::UP bundle)
{
- LockGuard guard(_lock);
+ std::lock_guard guard(_lock);
_bundles.push_back(bundle.get());
bundle.release();
}
diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
index dbf9f7025b6..135fc2d7562 100644
--- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
+++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h
@@ -2,7 +2,6 @@
#pragma once
-#include "sync.h"
#include "count_down_latch.h"
#include "thread.h"
#include "runnable.h"
@@ -94,8 +93,8 @@ public:
class Pool
{
private:
- Lock _lock;
- size_t _bundleSize;
+ std::mutex _lock;
+ size_t _bundleSize;
std::vector<SimpleThreadBundle*> _bundles;
public:
diff --git a/vespalib/src/vespa/vespalib/util/sync.cpp b/vespalib/src/vespa/vespalib/util/sync.cpp
index 3819b2b3369..ac55f12c341 100644
--- a/vespalib/src/vespa/vespalib/util/sync.cpp
+++ b/vespalib/src/vespa/vespalib/util/sync.cpp
@@ -19,47 +19,10 @@ Monitor::Monitor() noexcept
Monitor::Monitor(Monitor &&rhs) noexcept = default;
Monitor::~Monitor() = default;
-
-TryLock::TryLock(const Lock &lock)
- : _guard(*lock._mutex, std::try_to_lock),
- _cond(nullptr)
-{}
-
-TryLock::TryLock(const Monitor &mon)
- : _guard(*mon._mutex, std::try_to_lock),
- _cond(_guard ? mon._cond.get() : nullptr)
-{}
-
-TryLock::TryLock(TryLock &&rhs) noexcept
- : _guard(std::move(rhs._guard)),
- _cond(rhs._cond)
-{
- rhs._cond = nullptr;
-}
-
-TryLock::~TryLock() = default;
-
-bool
-TryLock::hasLock() const {
- return static_cast<bool>(_guard);
-}
-
-void
-TryLock::unlock() {
- if (_guard) {
- _guard.unlock();
- _cond = nullptr;
- }
-}
-
LockGuard::LockGuard() : _guard() {}
LockGuard::LockGuard(LockGuard &&rhs) noexcept : _guard(std::move(rhs._guard)) { }
LockGuard::LockGuard(const Lock &lock) : _guard(*lock._mutex) { }
-LockGuard::LockGuard(TryLock &&tlock) : _guard(std::move(tlock._guard))
-{
- tlock._cond = nullptr;
-}
LockGuard &
LockGuard::operator=(LockGuard &&rhs) noexcept{
@@ -93,16 +56,6 @@ MonitorGuard::MonitorGuard(const Monitor &monitor)
: _guard(*monitor._mutex),
_cond(monitor._cond.get())
{ }
-MonitorGuard::MonitorGuard(TryLock &&tlock)
- : _guard(),
- _cond(nullptr)
-{
- if (tlock._guard && tlock._cond != nullptr) {
- _guard = std::move(tlock._guard);
- _cond = tlock._cond;
- tlock._cond = nullptr;
- }
-}
MonitorGuard &
MonitorGuard::operator=(MonitorGuard &&rhs) noexcept {
diff --git a/vespalib/src/vespa/vespalib/util/sync.h b/vespalib/src/vespa/vespalib/util/sync.h
index b1227ce658e..3207206a753 100644
--- a/vespalib/src/vespa/vespalib/util/sync.h
+++ b/vespalib/src/vespa/vespalib/util/sync.h
@@ -70,89 +70,6 @@ public:
/**
- * @brief A TryLock object is used to try to obtain the lock on a Lock
- * or a Monitor without blocking.
- *
- * A TryLock will typically fail to obatin the lock if someone else
- * already has it. In that case, the TryLock object has no further
- * use.
- *
- * If the TryLock managed to acquire the lock, it can be passed over
- * to a LockGuard or MonitorGuard object. If the lock is not passed
- * on, the TryLock object will release it when it goes out of scope.
- *
- * Note that passing the lock obtained from a Lock to a MonitorGuard
- * is illegal. Also note that if the TryLock fails to aquire the lock,
- * it cannot be passed on. Trying to do so will result in an assert.
- *
- * copy/assignment of a TryLock is illegal.
- *
- * <pre>
- * Example:
- *
- * Lock lock;
- * TryLock tl(lock);
- * if (tl.hasLock()) {
- * LockGuard guard(tl)
- * ... do stuff
- * } // the lock is released as 'guard' goes out of scope
- * </pre>
- **/
-class TryLock
-{
-private:
- friend class LockGuard;
- friend class MonitorGuard;
-
- std::unique_lock<std::mutex> _guard;
- std::condition_variable *_cond;
-
-public:
- /**
- * @brief Try to obtain the lock represented by the given Lock object
- *
- * @param lock the lock to obtain
- **/
- TryLock(const Lock &lock);
-
- /**
- * @brief Try to lock the given Monitor
- *
- * @param mon the monitor to lock
- **/
- TryLock(const Monitor &mon);
-
- TryLock(TryLock &&rhs) noexcept;
-
- /**
- * @brief Release the lock held by this object, if any
- **/
- ~TryLock();
-
- TryLock(const TryLock &) = delete;
- TryLock &operator=(const TryLock &) = delete;
-
- TryLock &operator=(TryLock &&rhs) noexcept;
-
- /**
- * @brief Check whether this object holds a lock
- *
- * @return true if this object holds a lock
- **/
- bool hasLock() const;
- /**
- * @brief Release the lock held by this object.
- *
- * No methods may be invoked after invoking unlock (except the
- * destructor). Note that this method should only be used if you
- * need to release the lock before the object is destructed, as
- * the destructor will release the lock.
- **/
- void unlock();
-};
-
-
-/**
* @brief A LockGuard holds the lock on either a Lock or a Monitor.
*
* LockGuards are typically created on the stack to hold a lock within
@@ -191,17 +108,6 @@ public:
**/
LockGuard(const Lock &lock);
- /**
- * @brief Create a LockGuard from a TryLock.
- *
- * The TryLock may have been created from either a Lock or a
- * Monitor, but it must have managed to acquire the lock. The lock
- * will be handed over from the TryLock to the new object.
- *
- * @param tlock take the lock from this one
- **/
- LockGuard(TryLock &&tlock);
-
LockGuard &operator=(LockGuard &&rhs) noexcept;
/**
@@ -267,16 +173,6 @@ public:
* @param monitor take the lock on it
**/
MonitorGuard(const Monitor &monitor);
- /**
- * @brief Create a MonitorGuard from a TryLock.
- *
- * The TryLock must have been created from a Monitor, and it must
- * have managed to acquire the lock. The lock will be handed over
- * from the TryLock to the new object.
- *
- * @param tlock take the lock from this one
- **/
- MonitorGuard(TryLock &&tlock);
MonitorGuard &operator=(MonitorGuard &&rhs) noexcept;