aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2022-03-01 05:42:38 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2022-03-03 11:39:52 +0000
commit64c08801e0ac5094fb111c5fe3ea63cc7597506d (patch)
treea34f000d2743b864e22e322d9ce94b655c86ac97
parent6f78fdc9750ad3ac03b14166b6838c628487458c (diff)
Let the InvocationService drive the clock instead of having its own ticking loop.
Also use sleep_until to get intervals indendant of invoke cost as long as cost is within interval. This also also saves a clock sample and simplifies implementation.
-rw-r--r--searchcore/src/apps/tests/persistenceconformance_test.cpp4
-rw-r--r--searchcore/src/tests/grouping/grouping.cpp27
-rw-r--r--searchcore/src/tests/proton/docsummary/docsummary.cpp4
-rw-r--r--searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp7
-rw-r--r--searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp9
-rw-r--r--searchcore/src/tests/proton/documentdb/documentdb_test.cpp6
-rw-r--r--searchcore/src/tests/proton/matching/matching_test.cpp6
-rw-r--r--searchcore/src/tests/proton/matching/request_context/request_context_test.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/bmcluster/bm_node.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/matcher.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/executorthreadingservice.cpp1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/i_shared_threading_service.h6
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton.h1
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp7
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/shared_threading_service.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.h4
-rw-r--r--searchlib/src/tests/queryeval/simple_phrase/simple_phrase_test.cpp9
-rw-r--r--searchlib/src/tests/sortspec/multilevelsort.cpp13
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h3
-rw-r--r--staging_vespalib/src/tests/clock/clock_benchmark.cpp6
-rw-r--r--staging_vespalib/src/tests/clock/clock_test.cpp10
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt1
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/clock.cpp31
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/clock.h29
-rw-r--r--staging_vespalib/src/vespa/vespalib/util/doom.h4
-rw-r--r--vespalib/src/tests/invokeservice/invokeservice_test.cpp19
-rw-r--r--vespalib/src/vespa/vespalib/util/invokeservice.h4
-rw-r--r--vespalib/src/vespa/vespalib/util/invokeserviceimpl.cpp18
-rw-r--r--vespalib/src/vespa/vespalib/util/invokeserviceimpl.h8
36 files changed, 131 insertions, 151 deletions
diff --git a/searchcore/src/apps/tests/persistenceconformance_test.cpp b/searchcore/src/apps/tests/persistenceconformance_test.cpp
index fd0ace21955..4369666591f 100644
--- a/searchcore/src/apps/tests/persistenceconformance_test.cpp
+++ b/searchcore/src/apps/tests/persistenceconformance_test.cpp
@@ -171,7 +171,6 @@ private:
DummyFileHeaderContext _fileHeaderContext;
vespalib::string _tlsSpec;
matching::QueryLimiter _queryLimiter;
- vespalib::Clock _clock;
mutable DummyWireService _metricsWireService;
mutable MemoryConfigStores _config_stores;
vespalib::ThreadStackExecutor _summaryExecutor;
@@ -209,7 +208,7 @@ public:
tuneFileDocDB, HwInfo());
mgr.forwardConfig(b);
mgr.nextGeneration(_shared_service.transport(), 0ms);
- return DocumentDB::create(_baseDir, mgr.getConfig(), _tlsSpec, _queryLimiter, _clock, docType, bucketSpace,
+ return DocumentDB::create(_baseDir, mgr.getConfig(), _tlsSpec, _queryLimiter, docType, bucketSpace,
*b->getProtonConfigSP(), const_cast<DocumentDBFactory &>(*this),
_shared_service, _bucketExecutor, _tls, _metricsWireService,
_fileHeaderContext, _config_stores.getConfigStore(docType.toString()),
@@ -223,7 +222,6 @@ DocumentDBFactory::DocumentDBFactory(const vespalib::string &baseDir, int tlsLis
_fileHeaderContext(),
_tlsSpec(vespalib::make_string("tcp/localhost:%d", tlsListenPort)),
_queryLimiter(),
- _clock(),
_metricsWireService(),
_summaryExecutor(8, 128_Ki),
_shared_service(_summaryExecutor, _summaryExecutor),
diff --git a/searchcore/src/tests/grouping/grouping.cpp b/searchcore/src/tests/grouping/grouping.cpp
index 65c7361953e..a08d4703814 100644
--- a/searchcore/src/tests/grouping/grouping.cpp
+++ b/searchcore/src/tests/grouping/grouping.cpp
@@ -10,6 +10,7 @@
#include <vespa/searchcore/grouping/groupingsession.h>
#include <vespa/searchcore/proton/matching/sessionmanager.h>
#include <vespa/searchlib/test/mock_attribute_context.h>
+#include <vespa/vespalib/util/testclock.h>
#include <iostream>
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/log/log.h>
@@ -111,7 +112,7 @@ private:
};
struct DoomFixture {
- vespalib::Clock clock;
+ vespalib::TestClock clock;
steady_time timeOfDoom;
DoomFixture() : clock(), timeOfDoom(steady_time::max()) {}
};
@@ -168,7 +169,7 @@ TEST_F("testGroupingContextInitialization", DoomFixture()) {
nos << (uint32_t)1;
baseRequest.serialize(nos);
- GroupingContext context(f1.clock, f1.timeOfDoom, os.data(), os.size());
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom, os.data(), os.size());
ASSERT_TRUE(!context.empty());
GroupingContext::GroupingList list = context.getGroupingList();
ASSERT_TRUE(list.size() == 1);
@@ -198,7 +199,7 @@ TEST_F("testGroupingContextUsage", DoomFixture()) {
GroupingContext::GroupingPtr r1(new Grouping(request1));
GroupingContext::GroupingPtr r2(new Grouping(request2));
- GroupingContext context(f1.clock, f1.timeOfDoom);
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom);
ASSERT_TRUE(context.empty());
context.addGrouping(r1);
ASSERT_TRUE(context.getGroupingList().size() == 1);
@@ -220,7 +221,7 @@ TEST_F("testGroupingContextSerializing", DoomFixture()) {
nos << (uint32_t)1;
baseRequest.serialize(nos);
- GroupingContext context(f1.clock, f1.timeOfDoom);
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom);
GroupingContext::GroupingPtr bp(new Grouping(baseRequest));
context.addGrouping(bp);
context.serialize();
@@ -238,7 +239,7 @@ TEST_F("testGroupingManager", DoomFixture()) {
.addLevel(createGL(MU<AttributeNode>("attr1"), MU<AttributeNode>("attr2")))
.addLevel(createGL(MU<AttributeNode>("attr2"), MU<AttributeNode>("attr3")));
- GroupingContext context(f1.clock, f1.timeOfDoom);
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom);
GroupingContext::GroupingPtr bp(new Grouping(request1));
context.addGrouping(bp);
GroupingManager manager(context);
@@ -273,7 +274,7 @@ TEST_F("testGroupingSession", DoomFixture()) {
GroupingContext::GroupingPtr r1(new Grouping(request1));
GroupingContext::GroupingPtr r2(new Grouping(request2));
- GroupingContext initContext(f1.clock, f1.timeOfDoom);
+ GroupingContext initContext(f1.clock.clock(), f1.timeOfDoom);
initContext.addGrouping(r1);
initContext.addGrouping(r2);
SessionId id("foo");
@@ -305,7 +306,7 @@ TEST_F("testGroupingSession", DoomFixture()) {
}
// Test second pass
{
- GroupingContext context(f1.clock, f1.timeOfDoom);
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom);
GroupingContext::GroupingPtr r(new Grouping(request1));
r->setFirstLevel(1);
r->setLastLevel(1);
@@ -316,7 +317,7 @@ TEST_F("testGroupingSession", DoomFixture()) {
}
// Test last pass. Session should be marked as finished
{
- GroupingContext context(f1.clock, f1.timeOfDoom);
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom);
GroupingContext::GroupingPtr r(new Grouping(request1));
r->setFirstLevel(2);
r->setLastLevel(2);
@@ -340,7 +341,7 @@ TEST_F("testEmptySessionId", DoomFixture()) {
.addLevel(createGL(MU<AttributeNode>("attr2"), MU<AttributeNode>("attr3")));
GroupingContext::GroupingPtr r1(new Grouping(request1));
- GroupingContext initContext(f1.clock, f1.timeOfDoom);
+ GroupingContext initContext(f1.clock.clock(), f1.timeOfDoom);
initContext.addGrouping(r1);
SessionId id;
@@ -373,7 +374,7 @@ TEST_F("testSessionManager", DoomFixture()) {
.setResult(Int64ResultNode(0))));
GroupingContext::GroupingPtr r1(new Grouping(request1));
- GroupingContext initContext(f1.clock, f1.timeOfDoom);
+ GroupingContext initContext(f1.clock.clock(), f1.timeOfDoom);
initContext.addGrouping(r1);
SessionManager mgr(2);
@@ -431,7 +432,7 @@ TEST_F("test grouping fork/join", DoomFixture()) {
.setLastLevel(1);
GroupingContext::GroupingPtr g1(new Grouping(request));
- GroupingContext context(f1.clock, f1.timeOfDoom);
+ GroupingContext context(f1.clock.clock(), f1.timeOfDoom);
context.addGrouping(g1);
GroupingSession session(SessionId(), context, world.attributeContext);
session.prepareThreadContextCreation(4);
@@ -473,8 +474,8 @@ TEST_F("test session timeout", DoomFixture()) {
SessionId id1("foo");
SessionId id2("bar");
- GroupingContext initContext1(f1.clock, steady_time(duration(10)));
- GroupingContext initContext2(f1.clock, steady_time(duration(20)));
+ GroupingContext initContext1(f1.clock.clock(), steady_time(duration(10)));
+ GroupingContext initContext2(f1.clock.clock(), steady_time(duration(20)));
GroupingSession::UP s1(new GroupingSession(id1, initContext1, world.attributeContext));
GroupingSession::UP s2(new GroupingSession(id2, initContext2, world.attributeContext));
mgr.insert(std::move(s1));
diff --git a/searchcore/src/tests/proton/docsummary/docsummary.cpp b/searchcore/src/tests/proton/docsummary/docsummary.cpp
index faea1cc8b7c..ef8dc17dc0e 100644
--- a/searchcore/src/tests/proton/docsummary/docsummary.cpp
+++ b/searchcore/src/tests/proton/docsummary/docsummary.cpp
@@ -183,7 +183,6 @@ public:
storage::spi::dummy::DummyBucketExecutor _bucketExecutor;
bool _mkdirOk;
matching::QueryLimiter _queryLimiter;
- vespalib::Clock _clock;
DummyWireService _dummy;
::config::DirSpec _spec;
DocumentDBConfigHelper _configMgr;
@@ -204,7 +203,6 @@ public:
_bucketExecutor(2),
_mkdirOk(FastOS_File::MakeDirectory("tmpdb")),
_queryLimiter(),
- _clock(),
_dummy(),
_spec(TEST_PATH("")),
_configMgr(_spec, getDocTypeName()),
@@ -227,7 +225,7 @@ public:
if (! FastOS_File::MakeDirectory((std::string("tmpdb/") + docTypeName).c_str())) {
LOG_ABORT("should not be reached");
}
- _ddb = DocumentDB::create("tmpdb", _configMgr.getConfig(), "tcp/localhost:9013", _queryLimiter, _clock,
+ _ddb = DocumentDB::create("tmpdb", _configMgr.getConfig(), "tcp/localhost:9013", _queryLimiter,
DocTypeName(docTypeName), makeBucketSpace(), *b->getProtonConfigSP(), *this,
_shared_service, _bucketExecutor, _tls, _dummy, _fileHeaderContext,
std::make_unique<MemoryConfigStore>(),
diff --git a/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp b/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp
index 0e9eb926514..9e77047e578 100644
--- a/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp
@@ -28,6 +28,7 @@
#include <vespa/vespalib/io/fileutil.h>
#include <vespa/vespalib/util/size_literals.h>
#include <vespa/vespalib/util/threadstackexecutor.h>
+#include <vespa/vespalib/util/testclock.h>
using namespace config;
using namespace document;
@@ -146,7 +147,7 @@ struct MyDocumentDBReferenceResolver : public IDocumentDBReferenceResolver {
struct Fixture
{
- vespalib::Clock _clock;
+ vespalib::TestClock _clock;
matching::QueryLimiter _queryLimiter;
EmptyConstantValueFactory _constantValueFactory;
ConstantValueRepo _constantValueRepo;
@@ -175,7 +176,7 @@ Fixture::Fixture()
vespalib::mkdir(BASE_DIR);
initViewSet(_views);
_configurer = std::make_unique<Configurer>(_views._summaryMgr, _views.searchView, _views.feedView, _queryLimiter,
- _constantValueRepo, _clock, "test", 0);
+ _constantValueRepo, _clock.clock(), "test", 0);
}
Fixture::~Fixture() = default;
@@ -184,7 +185,7 @@ Fixture::initViewSet(ViewSet &views)
{
using IndexManager = proton::index::IndexManager;
using IndexConfig = proton::index::IndexConfig;
- auto matchers = std::make_shared<Matchers>(_clock, _queryLimiter, _constantValueRepo);
+ auto matchers = std::make_shared<Matchers>(_clock.clock(), _queryLimiter, _constantValueRepo);
auto indexMgr = make_shared<IndexManager>(BASE_DIR, IndexConfig(searchcorespi::index::WarmupConfig(), 2, 0), Schema(), 1,
views._reconfigurer, views._service.write(), _summaryExecutor,
TuneFileIndexManager(), TuneFileAttributes(), views._fileHeaderContext);
diff --git a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp
index 27636324835..68a92c73b44 100644
--- a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp
@@ -35,6 +35,7 @@
#include <vespa/vespalib/util/size_literals.h>
#include <vespa/vespalib/util/threadstackexecutor.h>
#include <vespa/vespalib/util/destructor_callbacks.h>
+#include <vespa/vespalib/util/testclock.h>
#include <vespa/config/subscription/sourcespec.h>
using namespace cloud::config::filedistribution;
@@ -215,9 +216,9 @@ struct MySearchableConfig
struct MySearchableContext
{
MyFastAccessContext _fastUpdCtx;
- QueryLimiter _queryLimiter;
- vespalib::Clock _clock;
- SearchableContext _ctx;
+ QueryLimiter _queryLimiter;
+ vespalib::TestClock _clock;
+ SearchableContext _ctx;
MySearchableContext(IThreadingService &writeService,
std::shared_ptr<bucketdb::BucketDBOwner> bucketDB,
IBucketDBHandlerInitializer & bucketDBHandlerInitializer);
@@ -236,7 +237,7 @@ MySearchableContext::MySearchableContext(IThreadingService &writeService,
IBucketDBHandlerInitializer & bucketDBHandlerInitializer)
: _fastUpdCtx(writeService, bucketDB, bucketDBHandlerInitializer),
_queryLimiter(), _clock(),
- _ctx(_fastUpdCtx._ctx, _queryLimiter, _clock, writeService.shared())
+ _ctx(_fastUpdCtx._ctx, _queryLimiter, _clock.clock(), writeService.shared())
{}
MySearchableContext::~MySearchableContext() = default;
diff --git a/searchcore/src/tests/proton/documentdb/documentdb_test.cpp b/searchcore/src/tests/proton/documentdb/documentdb_test.cpp
index c6a8df79a5e..1f3be7511da 100644
--- a/searchcore/src/tests/proton/documentdb/documentdb_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/documentdb_test.cpp
@@ -127,7 +127,6 @@ struct Fixture : public FixtureBase {
DummyFileHeaderContext _fileHeaderContext;
TransLogServer _tls;
matching::QueryLimiter _queryLimiter;
- vespalib::Clock _clock;
std::unique_ptr<ConfigStore> make_config_store();
Fixture();
@@ -151,8 +150,7 @@ Fixture::Fixture(bool file_config)
_db(),
_fileHeaderContext(),
_tls(_shared_service.transport(), "tmp", 9014, ".", _fileHeaderContext),
- _queryLimiter(),
- _clock()
+ _queryLimiter()
{
auto documenttypesConfig = std::make_shared<DocumenttypesConfig>();
DocumentType docType("typea", 0);
@@ -167,7 +165,7 @@ Fixture::Fixture(bool file_config)
tuneFileDocumentDB, HwInfo());
mgr.forwardConfig(b);
mgr.nextGeneration(_shared_service.transport(), 0ms);
- _db = DocumentDB::create(".", mgr.getConfig(), "tcp/localhost:9014", _queryLimiter, _clock, DocTypeName("typea"),
+ _db = DocumentDB::create(".", mgr.getConfig(), "tcp/localhost:9014", _queryLimiter, DocTypeName("typea"),
makeBucketSpace(),
*b->getProtonConfigSP(), _myDBOwner, _shared_service, _bucketExecutor, _tls, _dummy,
_fileHeaderContext, make_config_store(),
diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp
index 09bb67dbac9..187c0463da3 100644
--- a/searchcore/src/tests/proton/matching/matching_test.cpp
+++ b/searchcore/src/tests/proton/matching/matching_test.cpp
@@ -8,7 +8,6 @@
#include <vespa/searchcore/proton/documentmetastore/documentmetastore.h>
#include <vespa/searchcore/proton/matching/fakesearchcontext.h>
#include <vespa/searchcore/proton/matching/i_constant_value_repo.h>
-#include <vespa/searchcore/proton/matching/isearchcontext.h>
#include <vespa/searchcore/proton/matching/matcher.h>
#include <vespa/searchcore/proton/matching/querynodes.h>
#include <vespa/searchcore/proton/matching/sessionmanager.h>
@@ -37,6 +36,7 @@
#include <vespa/eval/eval/tensor_spec.h>
#include <vespa/eval/eval/value_codec.h>
#include <vespa/vespalib/objects/nbostream.h>
+#include <vespa/vespalib/util/testclock.h>
#include <vespa/log/log.h>
LOG_SETUP("matching_test");
@@ -120,7 +120,7 @@ struct MyWorld {
SessionManager::SP sessionManager;
DocumentMetaStore metaStore;
MatchingStats matchingStats;
- vespalib::Clock clock;
+ vespalib::TestClock clock;
QueryLimiter queryLimiter;
EmptyConstantValueRepo constantValueRepo;
@@ -344,7 +344,7 @@ struct MyWorld {
}
Matcher::SP createMatcher() {
- return std::make_shared<Matcher>(schema, config, clock, queryLimiter, constantValueRepo, RankingExpressions(), OnnxModels(), 0);
+ return std::make_shared<Matcher>(schema, config, clock.clock(), queryLimiter, constantValueRepo, RankingExpressions(), OnnxModels(), 0);
}
struct MySearchHandler : ISearchHandler {
diff --git a/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp b/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp
index 8ede5277d71..191c1718f61 100644
--- a/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp
+++ b/searchcore/src/tests/proton/matching/request_context/request_context_test.cpp
@@ -6,6 +6,7 @@
#include <vespa/searchcore/proton/matching/requestcontext.h>
#include <vespa/searchlib/attribute/attribute_blueprint_params.h>
#include <vespa/searchlib/fef/properties.h>
+#include <vespa/vespalib/util/testclock.h>
#include <vespa/vespalib/gtest/gtest.h>
#include <vespa/vespalib/objects/nbostream.h>
@@ -29,7 +30,7 @@ public:
class RequestContextTest : public ::testing::Test {
private:
- vespalib::Clock _clock;
+ vespalib::TestClock _clock;
vespalib::Doom _doom;
MyAttributeContext _attr_ctx;
Properties _props;
@@ -45,7 +46,7 @@ private:
public:
RequestContextTest()
: _clock(),
- _doom(_clock, vespalib::steady_time(), vespalib::steady_time(), false),
+ _doom(_clock.clock(), vespalib::steady_time(), vespalib::steady_time(), false),
_attr_ctx(),
_props(),
_request_ctx(_doom, _attr_ctx, _props, AttributeBlueprintParams()),
diff --git a/searchcore/src/vespa/searchcore/bmcluster/bm_node.cpp b/searchcore/src/vespa/searchcore/bmcluster/bm_node.cpp
index 85fd304f395..86dc38159e8 100644
--- a/searchcore/src/vespa/searchcore/bmcluster/bm_node.cpp
+++ b/searchcore/src/vespa/searchcore/bmcluster/bm_node.cpp
@@ -451,7 +451,6 @@ class MyBmNode : public BmNode
int _distributor_status_port;
vespalib::string _tls_spec;
proton::matching::QueryLimiter _query_limiter;
- vespalib::Clock _clock;
proton::DummyWireService _metrics_wire_service;
proton::MemoryConfigStores _config_stores;
vespalib::ThreadStackExecutor _summary_executor;
@@ -516,7 +515,6 @@ MyBmNode::MyBmNode(const vespalib::string& base_dir, int base_port, uint32_t nod
_distributor_status_port(port_number(base_port, PortBias::DISTRIBUTOR_STATUS_PORT)),
_tls_spec(vespalib::make_string("tcp/localhost:%d", _tls_listen_port)),
_query_limiter(),
- _clock(),
_metrics_wire_service(),
_config_stores(),
_summary_executor(8, 128_Ki),
@@ -591,7 +589,7 @@ MyBmNode::create_document_db(const BmClusterParams& params)
tuneFileDocDB, HwInfo());
mgr.forwardConfig(bootstrap_config);
mgr.nextGeneration(_shared_service.transport(), 0ms);
- _document_db = DocumentDB::create(_base_dir, mgr.getConfig(), _tls_spec, _query_limiter, _clock, _doc_type_name,
+ _document_db = DocumentDB::create(_base_dir, mgr.getConfig(), _tls_spec, _query_limiter, _doc_type_name,
_bucket_space, *bootstrap_config->getProtonConfigSP(), _document_db_owner,
_shared_service, *_persistence_engine, _tls,
_metrics_wire_service, _file_header_context,
diff --git a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp
index 435b6f718c7..56c3a1c761b 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp
@@ -1,12 +1,14 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "fakesearchcontext.h"
+#include <vespa/vespalib/util/testclock.h>
+
namespace proton::matching {
FakeSearchContext::FakeSearchContext(size_t initialNumDocs)
- : _clock(),
- _doom(_clock, vespalib::steady_time()),
+ : _clock(std::make_unique<vespalib::TestClock>()),
+ _doom(_clock->clock(), vespalib::steady_time()),
_selector(std::make_shared<search::FixedSourceSelector>(0, "fs", initialNumDocs)),
_indexes(std::make_shared<IndexCollection>(_selector)),
_attrSearchable(),
diff --git a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h
index 254f473c4ae..659bfc6c6d8 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h
@@ -11,6 +11,7 @@
#include <map>
#include <vector>
+namespace vespalib { class TestClock; }
namespace proton::matching {
using searchcorespi::FakeIndexSearchable;
@@ -23,7 +24,7 @@ public:
typedef search::queryeval::FakeSearchable FakeSearchable;
private:
- vespalib::Clock _clock;
+ std::unique_ptr<vespalib::TestClock> _clock;
vespalib::Doom _doom;
search::queryeval::ISourceSelector::SP _selector;
IndexCollection::SP _indexes;
diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp
index 4d94d2629fe..e945bbb850b 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp
@@ -150,7 +150,7 @@ Matcher::create_match_tools_factory(const search::engine::Request &request, ISea
: _stats.softDoomFactor())
: 0.95;
vespalib::duration safeLeft = std::chrono::duration_cast<vespalib::duration>(request.getTimeLeft() * factor);
- vespalib::steady_time safeDoom(_clock.getTimeNSAssumeRunning() + safeLeft);
+ vespalib::steady_time safeDoom(_clock.getTimeNS() + safeLeft);
if (softTimeoutEnabled) {
LOG(debug, "Soft-timeout computed factor=%1.3f, used factor=%1.3f, userSupplied=%d, softTimeout=%" PRId64,
_stats.softDoomFactor(), factor, hasFactorOverride, vespalib::count_ns(safeLeft));
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
index cf6193555e5..37a17fecfc1 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
@@ -140,7 +140,6 @@ DocumentDB::create(const vespalib::string &baseDir,
DocumentDBConfig::SP currentSnapshot,
const vespalib::string &tlsSpec,
matching::QueryLimiter &queryLimiter,
- const vespalib::Clock &clock,
const DocTypeName &docTypeName,
document::BucketSpace bucketSpace,
const ProtonConfig &protonCfg,
@@ -155,7 +154,7 @@ DocumentDB::create(const vespalib::string &baseDir,
const HwInfo &hwInfo)
{
return DocumentDB::SP(
- new DocumentDB(baseDir, std::move(currentSnapshot), tlsSpec, queryLimiter, clock, docTypeName, bucketSpace,
+ new DocumentDB(baseDir, std::move(currentSnapshot), tlsSpec, queryLimiter, docTypeName, bucketSpace,
protonCfg, owner, shared_service, bucketExecutor, tlsWriterFactory,
metricsWireService, fileHeaderContext, std::move(config_store), initializeThreads, hwInfo));
}
@@ -163,7 +162,6 @@ DocumentDB::DocumentDB(const vespalib::string &baseDir,
DocumentDBConfig::SP configSnapshot,
const vespalib::string &tlsSpec,
matching::QueryLimiter &queryLimiter,
- const vespalib::Clock &clock,
const DocTypeName &docTypeName,
document::BucketSpace bucketSpace,
const ProtonConfig &protonCfg,
@@ -219,7 +217,7 @@ DocumentDB::DocumentDB(const vespalib::string &baseDir,
_transient_usage_provider(std::make_shared<DocumentDBResourceUsageProvider>(*this)),
_feedHandler(std::make_unique<FeedHandler>(_writeService, tlsSpec, docTypeName, *this, _writeFilter, *this, tlsWriterFactory)),
_subDBs(*this, *this, *_feedHandler, _docTypeName, _writeService, shared_service.warmup(), fileHeaderContext,
- metricsWireService, getMetrics(), queryLimiter, clock, _configMutex, _baseDir, hwInfo),
+ metricsWireService, getMetrics(), queryLimiter, shared_service.clock(), _configMutex, _baseDir, hwInfo),
_maintenanceController(shared_service.transport(), _writeService.master(), shared_service.shared(), _refCount, _docTypeName),
_jobTrackers(),
_calc(),
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.h b/searchcore/src/vespa/searchcore/proton/server/documentdb.h
index 2030e6ffac9..e3d467fc3c1 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb.h
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.h
@@ -197,7 +197,6 @@ private:
DocumentDBConfig::SP currentSnapshot,
const vespalib::string &tlsSpec,
matching::QueryLimiter &queryLimiter,
- const vespalib::Clock &clock,
const DocTypeName &docTypeName,
document::BucketSpace bucketSpace,
const ProtonConfig &protonCfg,
@@ -228,7 +227,6 @@ public:
DocumentDBConfig::SP currentSnapshot,
const vespalib::string &tlsSpec,
matching::QueryLimiter &queryLimiter,
- const vespalib::Clock &clock,
const DocTypeName &docTypeName,
document::BucketSpace bucketSpace,
const ProtonConfig &protonCfg,
diff --git a/searchcore/src/vespa/searchcore/proton/server/executorthreadingservice.cpp b/searchcore/src/vespa/searchcore/proton/server/executorthreadingservice.cpp
index a268a6eac87..d6ecc6dd2d3 100644
--- a/searchcore/src/vespa/searchcore/proton/server/executorthreadingservice.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/executorthreadingservice.cpp
@@ -13,6 +13,7 @@ using vespalib::CpuUsage;
using vespalib::SequencedTaskExecutor;
using vespalib::SingleExecutor;
using vespalib::SyncableThreadExecutor;
+using vespalib::steady_time;
using OptimizeFor = vespalib::Executor::OptimizeFor;
using SharedFieldWriterExecutor = proton::ThreadingServiceConfig::SharedFieldWriterExecutor;
diff --git a/searchcore/src/vespa/searchcore/proton/server/i_shared_threading_service.h b/searchcore/src/vespa/searchcore/proton/server/i_shared_threading_service.h
index a467f9bc320..12377fd25e0 100644
--- a/searchcore/src/vespa/searchcore/proton/server/i_shared_threading_service.h
+++ b/searchcore/src/vespa/searchcore/proton/server/i_shared_threading_service.h
@@ -7,6 +7,7 @@ namespace vespalib {
class ISequencedTaskExecutor;
class ThreadExecutor;
class InvokeService;
+class Clock;
}
namespace proton {
@@ -51,6 +52,11 @@ public:
* Returns a shared transport object that can be utilized by multiple services.
*/
virtual FNET_Transport & transport() = 0;
+
+ /**
+ * Return a very cheap clock.
+ */
+ virtual const vespalib::Clock & clock() const = 0;
};
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
index 974c2522565..9bf6d19231e 100644
--- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
@@ -241,7 +241,6 @@ Proton::Proton(FastOS_ThreadPool & threadPool, FNET_Transport & transport, const
_shared_service(),
_compile_cache_executor_binding(),
_queryLimiter(),
- _clock(),
_distributionKey(-1),
_isInitializing(true),
_abortInit(false),
@@ -278,7 +277,6 @@ Proton::init(const BootstrapConfig::SP & configSnapshot)
setBucketCheckSumType(protonConfig);
setFS4Compression(protonConfig);
_shared_service = std::make_unique<SharedThreadingService>(SharedThreadingServiceConfig::make(protonConfig, hwInfo.cpu()), _transport);
- _clock.start(_shared_service->invokeService());
_diskMemUsageSampler = std::make_unique<DiskMemUsageSampler>(_shared_service->transport(), protonConfig.basedir,
diskMemUsageSamplerConfig(protonConfig, hwInfo));
@@ -473,7 +471,6 @@ Proton::~Proton()
_persistenceEngine.reset();
_tls.reset();
_compile_cache_executor_binding.reset();
- _clock.stop();
_shared_service.reset();
LOG(debug, "Explicit destructor done");
}
@@ -610,7 +607,6 @@ Proton::addDocumentDB(const document::DocumentType &docType,
documentDBConfig,
config.tlsspec,
_queryLimiter,
- _clock,
docTypeName,
bucketSpace,
config,
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.h b/searchcore/src/vespa/searchcore/proton/server/proton.h
index 73b8ae83ef2..58c9a8bda3e 100644
--- a/searchcore/src/vespa/searchcore/proton/server/proton.h
+++ b/searchcore/src/vespa/searchcore/proton/server/proton.h
@@ -111,7 +111,6 @@ private:
std::unique_ptr<SharedThreadingService> _shared_service;
vespalib::eval::CompileCache::ExecutorBinding::UP _compile_cache_executor_binding;
matching::QueryLimiter _queryLimiter;
- vespalib::Clock _clock;
uint32_t _distributionKey;
bool _isInitializing;
bool _abortInit;
diff --git a/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp b/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp
index b36dce23e28..cba2c1d458f 100644
--- a/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.cpp
@@ -3,13 +3,11 @@
#include "shared_threading_service.h"
#include <vespa/vespalib/util/blockingthreadstackexecutor.h>
#include <vespa/vespalib/util/cpu_usage.h>
-#include <vespa/vespalib/util/isequencedtaskexecutor.h>
#include <vespa/vespalib/util/sequencedtaskexecutor.h>
#include <vespa/vespalib/util/size_literals.h>
-#include <vespa/fnet/transport.h>
-#include <vespa/fastos/thread.h>
using vespalib::CpuUsage;
+using vespalib::steady_time;
VESPA_THREAD_STACK_TAG(proton_field_writer_executor)
VESPA_THREAD_STACK_TAG(proton_shared_executor)
@@ -28,7 +26,8 @@ SharedThreadingService::SharedThreadingService(const SharedThreadingServiceConfi
_field_writer(),
_invokeService(std::max(vespalib::adjustTimeoutByDetectedHz(1ms),
cfg.field_writer_config().reactionTime())),
- _invokeRegistrations()
+ _invokeRegistrations(),
+ _clock(_invokeService.nowPtr())
{
const auto& fw_cfg = cfg.field_writer_config();
if (fw_cfg.shared_field_writer() == SharedFieldWriterExecutor::DOCUMENT_DB) {
diff --git a/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.h b/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.h
index 349dcc2d0ce..463823f10cb 100644
--- a/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.h
+++ b/searchcore/src/vespa/searchcore/proton/server/shared_threading_service.h
@@ -5,6 +5,7 @@
#include "shared_threading_service_config.h"
#include <vespa/vespalib/util/threadstackexecutor.h>
#include <vespa/vespalib/util/syncable.h>
+#include <vespa/vespalib/util/clock.h>
#include <vespa/vespalib/util/invokeserviceimpl.h>
#include <memory>
@@ -22,7 +23,7 @@ private:
std::unique_ptr<vespalib::ISequencedTaskExecutor> _field_writer;
vespalib::InvokeServiceImpl _invokeService;
std::vector<Registration> _invokeRegistrations;
-
+ vespalib::Clock _clock;
public:
SharedThreadingService(const SharedThreadingServiceConfig& cfg, FNET_Transport & transport);
~SharedThreadingService() override;
@@ -35,6 +36,7 @@ public:
vespalib::ISequencedTaskExecutor* field_writer() override { return _field_writer.get(); }
vespalib::InvokeService & invokeService() override { return _invokeService; }
FNET_Transport & transport() override { return _transport; }
+ const vespalib::Clock & clock() const override { return _clock; }
};
}
diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.cpp b/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.cpp
index d695f4d8dc7..55f77ff41ea 100644
--- a/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.cpp
+++ b/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.cpp
@@ -8,7 +8,8 @@ MockSharedThreadingService::MockSharedThreadingService(ThreadExecutor& warmup_in
: _warmup(warmup_in),
_shared(shared_in),
_invokeService(10ms),
- _transport()
+ _transport(),
+ _clock(_invokeService.nowPtr())
{
}
diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.h b/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.h
index 7db208fa3ef..35c8ee46de5 100644
--- a/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.h
+++ b/searchcore/src/vespa/searchcore/proton/test/mock_shared_threading_service.h
@@ -4,6 +4,7 @@
#include "transport_helper.h"
#include <vespa/searchcore/proton/server/i_shared_threading_service.h>
#include <vespa/vespalib/util/invokeserviceimpl.h>
+#include <vespa/vespalib/util/clock.h>
namespace proton {
@@ -14,7 +15,7 @@ private:
ThreadExecutor & _shared;
vespalib::InvokeServiceImpl _invokeService;
Transport _transport;
-
+ vespalib::Clock _clock;
public:
MockSharedThreadingService(ThreadExecutor& warmup_in,
ThreadExecutor& shared_in);
@@ -24,6 +25,7 @@ public:
vespalib::ISequencedTaskExecutor* field_writer() override { return nullptr; }
vespalib::InvokeService & invokeService() override { return _invokeService; }
FNET_Transport & transport() override { return _transport.transport(); }
+ const vespalib::Clock & clock() const override { return _clock; }
};
}
diff --git a/searchlib/src/tests/queryeval/simple_phrase/simple_phrase_test.cpp b/searchlib/src/tests/queryeval/simple_phrase/simple_phrase_test.cpp
index 8879d591f5a..4877072eacd 100644
--- a/searchlib/src/tests/queryeval/simple_phrase/simple_phrase_test.cpp
+++ b/searchlib/src/tests/queryeval/simple_phrase/simple_phrase_test.cpp
@@ -9,6 +9,7 @@
#include <vespa/searchlib/fef/matchdatalayout.h>
#include <vespa/searchlib/query/tree/simplequery.h>
#include <vespa/searchlib/query/weight.h>
+#include <vespa/vespalib/util/testclock.h>
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/log/log.h>
@@ -211,8 +212,8 @@ void Test::requireThatIteratorHonorsFutureDoom() {
test.addTerm("foo", 0).addTerm("bar", 1);
test.fetchPostings(false);
- vespalib::Clock clock;
- vespalib::Doom futureDoom(clock, vespalib::steady_time::max());
+ vespalib::TestClock clock;
+ vespalib::Doom futureDoom(clock.clock(), vespalib::steady_time::max());
unique_ptr<SearchIterator> search(test.createSearch(false));
static_cast<SimplePhraseSearch &>(*search).setDoom(&futureDoom);
EXPECT_TRUE(!search->seek(1u));
@@ -225,8 +226,8 @@ void Test::requireThatIteratorHonorsDoom() {
test.addTerm("foo", 0).addTerm("bar", 1);
test.fetchPostings(false);
- vespalib::Clock clock;
- vespalib::Doom futureDoom(clock, vespalib::steady_time());
+ vespalib::TestClock clock;
+ vespalib::Doom futureDoom(clock.clock(), vespalib::steady_time());
unique_ptr<SearchIterator> search(test.createSearch(false));
static_cast<SimplePhraseSearch &>(*search).setDoom(&futureDoom);
EXPECT_TRUE(!search->seek(1u));
diff --git a/searchlib/src/tests/sortspec/multilevelsort.cpp b/searchlib/src/tests/sortspec/multilevelsort.cpp
index 576e1d1336c..88b105ec80c 100644
--- a/searchlib/src/tests/sortspec/multilevelsort.cpp
+++ b/searchlib/src/tests/sortspec/multilevelsort.cpp
@@ -7,6 +7,7 @@
#include <vespa/searchlib/attribute/attributecontext.h>
#include <vespa/searchlib/attribute/attributemanager.h>
#include <vespa/searchlib/uca/ucaconverter.h>
+#include <vespa/vespalib/util/testclock.h>
#include <vespa/vespalib/testkit/testapp.h>
#include <vespa/log/log.h>
LOG_SETUP("multilevelsort_test");
@@ -14,13 +15,9 @@ LOG_SETUP("multilevelsort_test");
using namespace search;
typedef FastS_SortSpec::VectorRef VectorRef;
-typedef IntegerAttributeTemplate<uint8_t> Uint8;
typedef IntegerAttributeTemplate<int8_t> Int8;
-typedef IntegerAttributeTemplate<uint16_t> Uint16;
typedef IntegerAttributeTemplate<int16_t> Int16;
-typedef IntegerAttributeTemplate<uint32_t> Uint32;
typedef IntegerAttributeTemplate<int32_t> Int32;
-typedef IntegerAttributeTemplate<uint64_t> Uint64;
typedef IntegerAttributeTemplate<int64_t> Int64;
typedef FloatingPointAttributeTemplate<float> Float;
typedef FloatingPointAttributeTemplate<double> Double;
@@ -239,8 +236,8 @@ MultilevelSortTest::sortAndCheck(const std::vector<Spec> &spec, uint32_t num,
hits[i]._rankValue = getRandomValue<uint32_t>();
}
- vespalib::Clock clock;
- vespalib::Doom doom(clock, vespalib::steady_time::max());
+ vespalib::TestClock clock;
+ vespalib::Doom doom(clock.clock(), vespalib::steady_time::max());
search::uca::UcaConverterFactory ucaFactory;
FastS_SortSpec sorter(7, doom, ucaFactory, _sortMethod);
// init sorter with sort data
@@ -396,8 +393,8 @@ TEST("require that all sort methods behave the same")
}
TEST("test that [docid] translates to [lid][paritionid]") {
- vespalib::Clock clock;
- vespalib::Doom doom(clock, vespalib::steady_time::max());
+ vespalib::TestClock clock;
+ vespalib::Doom doom(clock.clock(), vespalib::steady_time::max());
search::uca::UcaConverterFactory ucaFactory;
FastS_SortSpec asc(7, doom, ucaFactory);
RankedHit hits[2] = {RankedHit(91, 0.0), RankedHit(3, 2.0)};
diff --git a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.cpp b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.cpp
index ea4cbf84550..a123d3f6cd1 100644
--- a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.cpp
@@ -1,12 +1,14 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "fake_requestcontext.h"
+#include <vespa/vespalib/util/testclock.h>
+
namespace search::queryeval {
FakeRequestContext::FakeRequestContext(attribute::IAttributeContext * context, vespalib::steady_time softDoom, vespalib::steady_time hardDoom)
- : _clock(),
- _doom(_clock, softDoom, hardDoom, false),
+ : _clock(std::make_unique<vespalib::TestClock>()),
+ _doom(_clock->clock(), softDoom, hardDoom, false),
_attributeContext(context),
_query_tensor_name(),
_query_tensor(),
diff --git a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h
index 25a4fa559e0..a492f055cdb 100644
--- a/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h
+++ b/searchlib/src/vespa/searchlib/queryeval/fake_requestcontext.h
@@ -13,6 +13,7 @@
#include <vespa/vespalib/util/doom.h>
#include <limits>
+namespace vespalib { class TestClock; }
namespace search::queryeval {
class FakeRequestContext : public IRequestContext
@@ -47,7 +48,7 @@ public:
const search::attribute::AttributeBlueprintParams& get_attribute_blueprint_params() const override;
private:
- vespalib::Clock _clock;
+ std::unique_ptr<vespalib::TestClock> _clock;
const vespalib::Doom _doom;
attribute::IAttributeContext *_attributeContext;
vespalib::string _query_tensor_name;
diff --git a/staging_vespalib/src/tests/clock/clock_benchmark.cpp b/staging_vespalib/src/tests/clock/clock_benchmark.cpp
index c8d3e2a5aff..a51d83ae4dc 100644
--- a/staging_vespalib/src/tests/clock/clock_benchmark.cpp
+++ b/staging_vespalib/src/tests/clock/clock_benchmark.cpp
@@ -139,17 +139,16 @@ main(int , char *argv[])
NSVolatile nsVolatile;
NSAtomic nsAtomic;
vespalib::InvokeServiceImpl invoker(vespalib::from_s(1.0/frequency));
- Clock clock;
+ Clock clock(invoker.nowPtr());
TestClock nsClock(nsValue, 1.0/frequency);
TestClock nsVolatileClock(nsVolatile, 1.0/frequency);
TestClock nsAtomicClock(nsAtomic, 1.0/frequency);
- clock.start(invoker);
assert(pool.NewThread(&nsClock, nullptr) != nullptr);
assert(pool.NewThread(&nsVolatileClock, nullptr) != nullptr);
assert(pool.NewThread(&nsAtomicClock, nullptr) != nullptr);
benchmark("vespalib::Clock", pool, samples, numThreads, [&clock]() {
- return clock.getTimeNSAssumeRunning();
+ return clock.getTimeNS();
});
benchmark("uint64_t", pool, samples, numThreads, [&nsValue]() {
return steady_time (duration(nsValue._value));
@@ -175,6 +174,5 @@ main(int , char *argv[])
});
pool.Close();
- clock.stop();
return 0;
}
diff --git a/staging_vespalib/src/tests/clock/clock_test.cpp b/staging_vespalib/src/tests/clock/clock_test.cpp
index 2c6cbc0c876..b8ee4d7cc64 100644
--- a/staging_vespalib/src/tests/clock/clock_test.cpp
+++ b/staging_vespalib/src/tests/clock/clock_test.cpp
@@ -19,19 +19,11 @@ void waitForMovement(steady_time start, Clock & clock, vespalib::duration timeou
TEST("Test that clock is ticking forward") {
vespalib::InvokeServiceImpl invoker(50ms);
- Clock clock;
- clock.start(invoker);
+ Clock clock(invoker.nowPtr());
steady_time start = clock.getTimeNS();
waitForMovement(start, clock, 10s);
steady_time stop = clock.getTimeNS();
EXPECT_TRUE(stop > start);
- std::this_thread::sleep_for(1s);
- start = clock.getTimeNS();
- waitForMovement(start, clock, 10s);
- clock.stop();
- steady_time stop2 = clock.getTimeNS();
- EXPECT_TRUE(stop2 > stop);
- EXPECT_TRUE(vespalib::count_ms(stop2 - stop) > 1000);
}
TEST_MAIN() { TEST_RUN_ALL(); } \ No newline at end of file
diff --git a/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt b/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt
index e69dd36d6f5..2912ac2397b 100644
--- a/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt
+++ b/staging_vespalib/src/vespa/vespalib/util/CMakeLists.txt
@@ -23,6 +23,7 @@ vespa_add_library(staging_vespalib_vespalib_util OBJECT
shutdownguard.cpp
scheduledexecutor.cpp
singleexecutor.cpp
+ testclock.cpp
xmlserializable.cpp
xmlstream.cpp
DEPENDS
diff --git a/staging_vespalib/src/vespa/vespalib/util/clock.cpp b/staging_vespalib/src/vespa/vespalib/util/clock.cpp
index a4b9ed0fd5d..ad9d6d534f9 100644
--- a/staging_vespalib/src/vespa/vespalib/util/clock.cpp
+++ b/staging_vespalib/src/vespa/vespalib/util/clock.cpp
@@ -1,37 +1,16 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "clock.h"
-#include <vespa/vespalib/util/invokeservice.h>
-
+#include <cassert>
namespace vespalib {
-Clock::Clock() :
- _timeNS(0u),
- _running(false),
- _invokeRegistration()
+Clock::Clock(const std::atomic<steady_time> * source) noexcept
+ : _timeNS(source)
{
- setTime();
+ assert(_timeNS != nullptr);
+ static_assert(std::atomic<steady_time>::is_always_lock_free);
}
Clock::~Clock() = default;
-void Clock::setTime() const
-{
- _timeNS.store(count_ns(steady_clock::now().time_since_epoch()), std::memory_order_relaxed);
-}
-
-void
-Clock::start(InvokeService & invoker)
-{
- _running.store(true, std::memory_order_relaxed);
- _invokeRegistration = invoker.registerInvoke([this]() { setTime(); });
-}
-
-void
-Clock::stop()
-{
- _running.store(false, std::memory_order_relaxed);
- _invokeRegistration.reset();
-}
-
}
diff --git a/staging_vespalib/src/vespa/vespalib/util/clock.h b/staging_vespalib/src/vespa/vespalib/util/clock.h
index d4cffc200fe..0d160a98654 100644
--- a/staging_vespalib/src/vespa/vespalib/util/clock.h
+++ b/staging_vespalib/src/vespa/vespalib/util/clock.h
@@ -7,9 +7,6 @@
namespace vespalib {
-class IDestructorCallback;
-class InvokeService;
-
/**
* Clock is a clock that updates the time at defined intervals.
* It is intended used where you want to check the time with low cost, but where
@@ -19,28 +16,18 @@ class InvokeService;
class Clock
{
private:
- mutable std::atomic<int64_t> _timeNS;
- std::atomic<bool> _running;
- std::unique_ptr<IDestructorCallback> _invokeRegistration;
-
- void setTime() const;
+ const std::atomic<steady_time> *_timeNS;
public:
- Clock();
+ Clock(const std::atomic<steady_time> * source) noexcept;
+ Clock(const Clock &) = delete;
+ Clock & operator =(const Clock &) = delete;
+ Clock(Clock &&) = delete;
+ Clock & operator =(Clock &&) = delete;
~Clock();
- vespalib::steady_time getTimeNS() const {
- if (!_running) {
- setTime();
- }
- return getTimeNSAssumeRunning();
- }
- vespalib::steady_time getTimeNSAssumeRunning() const {
- return vespalib::steady_time(std::chrono::nanoseconds(_timeNS.load(std::memory_order_relaxed)));
+ vespalib::steady_time getTimeNS() const noexcept {
+ return vespalib::steady_time(_timeNS->load(std::memory_order_relaxed));
}
-
- void start(InvokeService & invoker);
- void stop();
};
}
-
diff --git a/staging_vespalib/src/vespa/vespalib/util/doom.h b/staging_vespalib/src/vespa/vespalib/util/doom.h
index b9a7e76b8af..e7db0795fb7 100644
--- a/staging_vespalib/src/vespa/vespalib/util/doom.h
+++ b/staging_vespalib/src/vespa/vespalib/util/doom.h
@@ -14,8 +14,8 @@ public:
Doom(const Clock &clock, steady_time softDoom,
steady_time hardDoom, bool explicitSoftDoom);
- bool soft_doom() const { return (_clock.getTimeNSAssumeRunning() > _softDoom); }
- bool hard_doom() const { return (_clock.getTimeNSAssumeRunning() > _hardDoom); }
+ bool soft_doom() const { return (_clock.getTimeNS() > _softDoom); }
+ bool hard_doom() const { return (_clock.getTimeNS() > _hardDoom); }
duration soft_left() const { return _softDoom - _clock.getTimeNS(); }
duration hard_left() const { return _hardDoom - _clock.getTimeNS(); }
bool isExplicitSoftDoom() const { return _isExplicitSoftDoom; }
diff --git a/vespalib/src/tests/invokeservice/invokeservice_test.cpp b/vespalib/src/tests/invokeservice/invokeservice_test.cpp
index 1d4791f4a33..d56eb28e6c7 100644
--- a/vespalib/src/tests/invokeservice/invokeservice_test.cpp
+++ b/vespalib/src/tests/invokeservice/invokeservice_test.cpp
@@ -29,6 +29,25 @@ TEST("require that wakeup is called") {
EXPECT_EQUAL(countAtStop, a._count);
}
+TEST("require that now is moving forward") {
+ InvokeCounter a;
+ InvokeServiceImpl service(1ms);
+ EXPECT_EQUAL(0u, a._count);
+ steady_time prev = steady_clock::now();
+ auto ra = service.registerInvoke([&prev, &a, now=service.nowPtr() ]() noexcept {
+ EXPECT_GREATER(now->load(), prev);
+ prev = now->load();
+ a.inc();
+ });
+ EXPECT_TRUE(ra);
+ a.wait_for_atleast(100);
+ ra.reset();
+ EXPECT_GREATER_EQUAL(a._count, 100u);
+ steady_time now = steady_clock::now();
+ EXPECT_GREATER(now, prev);
+ EXPECT_LESS(now - prev, 5s);
+}
+
TEST("require that same wakeup can be registered multiple times.") {
InvokeCounter a;
InvokeCounter b;
diff --git a/vespalib/src/vespa/vespalib/util/invokeservice.h b/vespalib/src/vespa/vespalib/util/invokeservice.h
index 3e3973234d1..22bee0d4526 100644
--- a/vespalib/src/vespa/vespalib/util/invokeservice.h
+++ b/vespalib/src/vespa/vespalib/util/invokeservice.h
@@ -3,6 +3,7 @@
#pragma once
#include "idestructorcallback.h"
+#include "time.h"
#include <functional>
namespace vespalib {
@@ -13,8 +14,9 @@ namespace vespalib {
**/
class InvokeService {
public:
+ using InvokeFunc = std::function<void()>;
virtual ~InvokeService() = default;
- virtual std::unique_ptr<IDestructorCallback> registerInvoke(std::function<void()> func) = 0;
+ virtual std::unique_ptr<IDestructorCallback> registerInvoke(InvokeFunc func) = 0;
};
}
diff --git a/vespalib/src/vespa/vespalib/util/invokeserviceimpl.cpp b/vespalib/src/vespa/vespalib/util/invokeserviceimpl.cpp
index ffa0825c950..eac84568ec2 100644
--- a/vespalib/src/vespa/vespalib/util/invokeserviceimpl.cpp
+++ b/vespalib/src/vespa/vespalib/util/invokeserviceimpl.cpp
@@ -7,11 +7,12 @@ namespace vespalib {
InvokeServiceImpl::InvokeServiceImpl(duration napTime)
: _naptime(napTime),
+ _now(steady_clock::now()),
_lock(),
_currId(0),
_closed(false),
_toInvoke(),
- _thread()
+ _thread(std::make_unique<std::thread>([this]() { runLoop(); }))
{
}
@@ -22,9 +23,7 @@ InvokeServiceImpl::~InvokeServiceImpl()
assert(_toInvoke.empty());
_closed = true;
}
- if (_thread) {
- _thread->join();
- }
+ _thread->join();
}
class InvokeServiceImpl::Registration : public IDestructorCallback {
@@ -44,20 +43,17 @@ private:
};
std::unique_ptr<IDestructorCallback>
-InvokeServiceImpl::registerInvoke(VoidFunc func) {
+InvokeServiceImpl::registerInvoke(InvokeFunc func) {
std::lock_guard guard(_lock);
uint64_t id = _currId++;
_toInvoke.emplace_back(id, std::move(func));
- if ( ! _thread) {
- _thread = std::make_unique<std::thread>([this]() { runLoop(); });
- }
return std::make_unique<Registration>(this, id);
}
void
InvokeServiceImpl::unregister(uint64_t id) {
std::lock_guard guard(_lock);
- auto found = std::find_if(_toInvoke.begin(), _toInvoke.end(), [id](const std::pair<uint64_t, VoidFunc> & a) {
+ auto found = std::find_if(_toInvoke.begin(), _toInvoke.end(), [id](const IdAndFunc & a) {
return id == a.first;
});
assert (found != _toInvoke.end());
@@ -68,6 +64,8 @@ void
InvokeServiceImpl::runLoop() {
bool done = false;
while ( ! done ) {
+ const steady_time now = steady_clock::now();
+ _now.store(now, std::memory_order_relaxed);
{
std::lock_guard guard(_lock);
for (auto & func: _toInvoke) {
@@ -76,7 +74,7 @@ InvokeServiceImpl::runLoop() {
done = _closed;
}
if ( ! done) {
- std::this_thread::sleep_for(_naptime);
+ std::this_thread::sleep_until(now + _naptime);
}
}
diff --git a/vespalib/src/vespa/vespalib/util/invokeserviceimpl.h b/vespalib/src/vespa/vespalib/util/invokeserviceimpl.h
index 3b0c7690731..2448e381610 100644
--- a/vespalib/src/vespa/vespalib/util/invokeserviceimpl.h
+++ b/vespalib/src/vespa/vespalib/util/invokeserviceimpl.h
@@ -14,22 +14,24 @@ namespace vespalib {
* An invoke service what will invoke the given function with at specified frequency.
*/
class InvokeServiceImpl : public InvokeService {
- using VoidFunc = std::function<void()>;
public:
InvokeServiceImpl(duration napTime);
InvokeServiceImpl(const InvokeServiceImpl &) = delete;
InvokeServiceImpl & operator=(const InvokeServiceImpl &) = delete;
~InvokeServiceImpl() override;
- std::unique_ptr<IDestructorCallback> registerInvoke(VoidFunc func) override;
+ std::unique_ptr<IDestructorCallback> registerInvoke(InvokeFunc func) override;
+ const std::atomic<steady_time> * nowPtr() const { return &_now; }
private:
+ using IdAndFunc = std::pair<uint64_t, InvokeFunc>;
class Registration;
void unregister(uint64_t id);
void runLoop();
duration _naptime;
+ std::atomic<steady_time> _now;
std::mutex _lock;
uint64_t _currId;
bool _closed;
- std::vector<std::pair<uint64_t, VoidFunc>> _toInvoke;
+ std::vector<IdAndFunc> _toInvoke;
std::unique_ptr<std::thread> _thread;
};