Skip to content

Commit

Permalink
bump Emscripten to 3.1.56
Browse files Browse the repository at this point in the history
   * ioThreadPool is not default-initialised any more as it is injected by the Graph/Scheduler and anyway needed by custom BlockinIO declared blocks that need a default thread pool

   * added optional sleep as workaround for incomplete std::atomic implementation (at least it seems for nodejs)

   * extra diagnostics for qa_Messages unit-test

   * some minor fixes of conversion warnings

Signed-off-by: Ralph J. Steinhagen <[email protected]>
  • Loading branch information
RalphSteinhagen committed May 19, 2024
1 parent afff8da commit 4871965
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 21 deletions.
19 changes: 10 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,20 @@ if (EMSCRIPTEN)
)
add_link_options(
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s ASSERTIONS=1"
"SHELL:-s INITIAL_MEMORY=256MB"
"SHELL:-s MAXIMUM_MEMORY=1GB"
"SHELL:-s SAFE_HEAP=1"
"SHELL:-s ASSERTIONS=2"
"SHELL:-s STACK_OVERFLOW_CHECK=2"
"SHELL:-g" # enable debugging information
"SHELL:-gsource-map"
"SHELL:--profiling-funcs"
"SHELL:--emit-symbol-map"
# "SHELL:-s SAFE_HEAP=1" # additional for debug
# "SHELL:-s ASSERTIONS=2" # additional for debug
# "SHELL:-s STACK_OVERFLOW_CHECK=2" # additional for debug
# "SHELL:-g" # additional for debug
# "SHELL:-gsource-map" # additional for debug
# "SHELL:--profiling-funcs" # additional for debug
# "SHELL:--emit-symbol-map" # additional for debug
-fwasm-exceptions
-pthread
"SHELL:-s PTHREAD_POOL_SIZE=30"
"SHELL:-s PTHREAD_POOL_SIZE=60"
"SHELL:-s FETCH=1"
"SHELL:-s WASM=1" # output as web-assembly
)
endif ()

Expand Down
7 changes: 4 additions & 3 deletions blocks/basic/include/gnuradio-4.0/basic/clock_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,10 @@ ClockSource Documentation -- add here

if (samplesToNextTag < samplesToNextTimeTag) {
if (next_tag < tags.size() && samplesToNextTag <= samplesToProduce) {
const auto tagDeltaIndex = tags[next_tag].index - static_cast<Tag::signed_index_type>(n_samples_produced); // position w.r.t. start of this chunk
const auto signedSamplesProduced = static_cast<Tag::signed_index_type>(n_samples_produced);
const auto tagDeltaIndex = tags[next_tag].index - signedSamplesProduced; // position w.r.t. start of this chunk
if (verbose_console) {
gr::testing::print_tag(tags[next_tag], fmt::format("{}::processBulk(...)\t publish tag at {:6}", this->name, n_samples_produced + tagDeltaIndex));
gr::testing::print_tag(tags[next_tag], fmt::format("{}::processBulk(...)\t publish tag at {:6}", this->name, signedSamplesProduced + tagDeltaIndex));
}
out.publishTag(tags[next_tag].map, tagDeltaIndex);
samplesToProduce = samplesToNextTag;
Expand All @@ -154,7 +155,7 @@ ClockSource Documentation -- add here
if (verbose_console) {
fmt::println("{}::processBulk(...)\t publish tag-time at {:6}, time:{}ns", this->name, samplesToNextTimeTag, tag_times[next_time_tag]);
}
out.publishTag(metaInfo, samplesToNextTimeTag);
out.publishTag(metaInfo, static_cast<Tag::signed_index_type>(samplesToNextTimeTag));
samplesToProduce = samplesToNextTimeTag;
next_time_tag++;
}
Expand Down
2 changes: 1 addition & 1 deletion blocks/basic/include/gnuradio-4.0/basic/common_blocks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct MultiAdder : public gr::Block<MultiAdder<T>> {
std::vector<gr::PortIn<T>> inputs;
gr::PortOut<T> out;

gr::Annotated<gr::Size_t, "n_inputs", gr::Visible, gr::Doc<"variable number of inputs">, gr::Limits<1U, 32U>> n_inputs = 0U;
gr::Annotated<gr::Size_t, "n_inputs", gr::Visible, gr::Doc<"variable number of inputs">, gr::Limits<1U, 32U>> n_inputs{ 0U };

void
settingsChanged(const gr::property_map &old_settings, const gr::property_map &new_settings) {
Expand Down
11 changes: 8 additions & 3 deletions core/include/gnuradio-4.0/Block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,9 +422,8 @@ class Block : public lifecycle::StateMachine<Derived>, //
alignas(hardware_destructive_interference_size) std::atomic<std::size_t> ioRequestedWork{ std::numeric_limits<std::size_t>::max() };
alignas(hardware_destructive_interference_size) work::Counter ioWorkDone{};
alignas(hardware_destructive_interference_size) std::atomic<work::Status> ioLastWorkStatus{ work::Status::OK };
alignas(hardware_destructive_interference_size) std::shared_ptr<gr::Sequence> progress = std::make_shared<gr::Sequence>();
alignas(hardware_destructive_interference_size) std::shared_ptr<gr::thread_pool::BasicThreadPool> ioThreadPool = std::make_shared<gr::thread_pool::BasicThreadPool>(
"block_thread_pool", gr::thread_pool::TaskType::IO_BOUND, 2UZ, std::numeric_limits<uint32_t>::max());
alignas(hardware_destructive_interference_size) std::shared_ptr<gr::Sequence> progress = std::make_shared<gr::Sequence>();
alignas(hardware_destructive_interference_size) std::shared_ptr<gr::thread_pool::BasicThreadPool> ioThreadPool;
alignas(hardware_destructive_interference_size) std::atomic<bool> ioThreadRunning{ false };

constexpr static TagPropagationPolicy tag_policy = TagPropagationPolicy::TPP_ALL_TO_ALL;
Expand Down Expand Up @@ -453,7 +452,9 @@ class Block : public lifecycle::StateMachine<Derived>, //
return "please add a public 'using Description = Doc<\"...\">' documentation annotation to your block definition";
}
}();
#ifndef __EMSCRIPTEN__
static_assert(std::atomic<lifecycle::State>::is_always_lock_free, "std::atomic<lifecycle::State> is not lock-free");
#endif

//
static property_map
Expand Down Expand Up @@ -1697,6 +1698,10 @@ class Block : public lifecycle::StateMachine<Derived>, //
bool expectedThreadState = false;
if (lifecycle::isActive(this->state()) && this->ioThreadRunning.compare_exchange_strong(expectedThreadState, true, std::memory_order_acq_rel)) {
if constexpr (useIoThread) { // use graph-provided ioThreadPool
if (!ioThreadPool) {
emitErrorMessage("work(..)", "blockingIO with useIoThread - no ioThreadPool being set");
return { requested_work, 0UZ, work::Status::ERROR };
}
ioThreadPool->execute([this]() {
assert(lifecycle::isActive(this->state()));

Expand Down
3 changes: 3 additions & 0 deletions core/include/gnuradio-4.0/Scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ class SchedulerBase : public Block<Derived> {
something_happened = true;
}
}
#ifdef __EMSCRIPTEN__
std::this_thread::sleep_for(std::chrono::microseconds(10u)); // workaround for incomplete std::atomic implementation (at least it seems for nodejs)
#endif
return { requestedWorkAllBlocks, performedWorkAllBlocks, something_happened ? work::Status::OK : work::Status::DONE };
}

Expand Down
24 changes: 20 additions & 4 deletions core/test/qa_Messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ const boost::ut::suite MessagesTests = [] {
using ResultCheck = std::function<std::optional<bool>()>;
SendCommand cmd = [] {};
ResultCheck check = [] { return true; };
std::chrono::milliseconds delay = 0ms; // delay after 'cmd' which the reply is being checked
std::chrono::milliseconds delay = 1ms; // delay after 'cmd' which the reply is being checked
std::chrono::milliseconds timeout = 1s; // time-out for the 'check' test
};

Expand All @@ -517,9 +517,18 @@ const boost::ut::suite MessagesTests = [] {
fmt::println("##### starting test for scheduler {}", gr::meta::type_name<decltype(scheduler)>());
std::fflush(stdout);

std::thread testWorker([&commands] {
std::this_thread::sleep_for(1s);
std::thread testWorker([&scheduler, &commands] {
fmt::println("starting testWorker.");
std::fflush(stdout);
while (scheduler.state() != gr::lifecycle::State::RUNNING) { // wait until scheduler is running
std::this_thread::sleep_for(40ms);
}
fmt::println("scheduler is running.");
std::fflush(stdout);

for (auto &[command, resultCheck, delay, timeout] : commands) {
fmt::print("executing command: ");
std::fflush(stdout);
command(); // execute the command
std::this_thread::sleep_for(delay); // wait for approximate time when command should be expected to be applied

Expand Down Expand Up @@ -548,8 +557,15 @@ const boost::ut::suite MessagesTests = [] {
}
}
});

fmt::println("starting scheduler {}", gr::meta::type_name<decltype(scheduler)>());
std::fflush(stdout);
expect(scheduler.runAndWait().has_value());
testWorker.join();
fmt::println("stopped scheduler {}", gr::meta::type_name<decltype(scheduler)>());

if (testWorker.joinable()) {
testWorker.join();
}

fmt::println("##### finished test for scheduler {} - produced {} samples", gr::meta::type_name<decltype(scheduler)>(), sink.n_samples_produced);
} | std::tuple<std::integral_constant<scheduler::ExecutionPolicy, scheduler::singleThreaded>, std::integral_constant<scheduler::ExecutionPolicy, scheduler::multiThreaded>>{};
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ ENV JAVA_HOME=/opt/java/openjdk \
LC_ALL=en_US.UTF-8 \
CMAKE_MAKE_PROGRAM=ninja \
EMSDK_HOME=/opt/emsdk \
EMSDK_VERSION=3.1.52
EMSDK_VERSION=3.1.56

# Install compilers, package managers and build-tools
# As we are using the the ubuntu prerelease llvm and cmake are fresh enough, readd these if the version is not sufficient anymore
Expand Down

0 comments on commit 4871965

Please sign in to comment.