Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/SchemeProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <string>
#include "Task.h"
#include "EXTThread.h"
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <queue>
Expand Down Expand Up @@ -92,7 +93,10 @@ class SchemeProcess {
int16_t m_serverPort;
bool m_banner;
std::string m_initExpr;
bool m_libsLoaded;
// Set once by the task thread after the runtime libs finish loading.
// Read by the server thread spin-waiting in serverImpl(); must be
// synchronised.
std::atomic<bool> m_libsLoaded;
std::recursive_mutex m_guardMutex;
std::condition_variable_any m_guardCond;
bool m_running;
Expand Down
12 changes: 10 additions & 2 deletions include/UNIV.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#ifndef UNIV_H
#define UNIV_H

#include <atomic>
#include <cstdint>
#include <BranchPrediction.h>

Expand Down Expand Up @@ -108,8 +109,15 @@ extern std::string SHARE_DIR;
EXPORT uint32_t CHANNELS;
EXPORT uint32_t IN_CHANNELS;
EXPORT uint32_t SAMPLE_RATE;
EXPORT volatile uint64_t TIME;
extern uint64_t DEVICE_TIME;
// TIME is written by the scheduler thread (TaskScheduler::timeSlice) and
// read from every other thread; atomic<uint64_t> gives a lock-free load/
// store on all tier-1 platforms. DEVICE_TIME is written by the audio
// callback and read from other threads, same story. The xtlang JIT
// accesses TIME via @TIME in runtime/bitcode.ll as a plain i64 load — OK
// because the layout of std::atomic<uint64_t> is a single uint64_t on
// all supported compilers.
EXPORT std::atomic<uint64_t> TIME;
extern std::atomic<uint64_t> DEVICE_TIME;
extern double AUDIO_CLOCK_BASE;
extern double AUDIO_CLOCK_NOW;
extern uint64_t TIME_DIVISION;
Expand Down
4 changes: 2 additions & 2 deletions src/AudioDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ int audioCallback(const void* InputBuffer, void* OutputBuffer, unsigned long Fra
auto sched(reinterpret_cast<TaskScheduler*>(UserData));
UNIV::DEVICE_TIME += FramesPerBuffer;
if (likely(UNIV::TIME_DIVISION == 1)) {
UNIV::TIME = UNIV::DEVICE_TIME;
UNIV::TIME.store(UNIV::DEVICE_TIME.load());
}
if (unlikely(AudioDevice::CLOCKBASE < 1.0)) {
AudioDevice::CLOCKBASE = getRealTime();
Expand Down Expand Up @@ -320,7 +320,7 @@ int audioCallback(const void* InputBuffer, void* OutputBuffer, unsigned long Fra
llvm_zone_t* zone = extemp::EXTZones::llvm_peek_zone_stack();
auto dat(reinterpret_cast<float*>(OutputBuffer));
auto in(reinterpret_cast<const float*>(InputBuffer));
auto time(UNIV::DEVICE_TIME);
uint64_t time(UNIV::DEVICE_TIME);
if (likely(!UNIV::IN_CHANNELS)) {
float dummy(0.0);
for (uint64_t i = 0; i < FramesPerBuffer; ++i, ++time) {
Expand Down
4 changes: 2 additions & 2 deletions src/SchemeProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ void* SchemeProcess::taskImpl()
resetOutportString();
} else {
if (m_banner) {
auto time(UNIV::TIME);
uint64_t time(UNIV::TIME);
auto hours(time / UNIV::HOUR());
time -= hours * UNIV::HOUR();
auto minutes(time / UNIV::MINUTE());
Expand Down Expand Up @@ -520,7 +520,7 @@ void* SchemeProcess::serverImpl()
std::string outString;
if (m_banner) {
outString += sm_banner;
auto time(UNIV::TIME);
uint64_t time(UNIV::TIME);
auto hours(time / UNIV::HOUR());
time -= hours * UNIV::HOUR();
auto minutes(time / UNIV::MINUTE());
Expand Down
7 changes: 5 additions & 2 deletions src/UNIV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,11 @@ uint32_t NUM_FRAMES = 1024;
uint32_t CHANNELS = 2;
uint32_t IN_CHANNELS = 0;
uint32_t SAMPLE_RATE = 44100;
volatile uint64_t TIME = 0l;
uint64_t DEVICE_TIME = 0l;
std::atomic<uint64_t> TIME{0};
std::atomic<uint64_t> DEVICE_TIME{0};
static_assert(std::atomic<uint64_t>::is_always_lock_free,
"std::atomic<uint64_t> must be lock-free so the xtlang JIT's "
"plain i64 loads of @TIME remain compatible");
double AUDIO_CLOCK_NOW = 0.0;
double AUDIO_CLOCK_BASE = 0.0;
uint64_t TIME_DIVISION = 1;
Expand Down
Loading