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
32 changes: 32 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
on:
push:
branches: ['**']
pull_request:
branches: ['**']

jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Install deps (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends cmake ninja-build

- name: Install deps (macOS)
if: runner.os == 'macOS'
run: brew install cmake ninja

- name: Configure
run: cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Debug

- name: Build
run: cmake --build build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/build/
2 changes: 2 additions & 0 deletions netutils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ set(OAN_UTILS_SOURCES
udp.h
LowLatSocket.cpp
LowLatSocket.h
rt.h
rt.cpp
)

if(EMBEDDED_BUILD)
Expand Down
71 changes: 71 additions & 0 deletions netutils/rt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// This file is part of the Open Audio Live System project, a live audio environment
// Copyright (c) 2026 - Jonathan D Reichardt
//
// This project is distributed under the Creative Commons CC-BY-NC-SA licence. https://creativecommons.org/licenses/by-nc-sa/4.0


#include "rt.h"


#ifdef __linux__
#include <iostream>
#include <sched.h>
#include <ctime>
#else
#include <ctime>
#endif

namespace oals::rt {
#ifdef __linux__
void set_thread_realtime(uint8_t prio) {
sched_param sparams{};
sparams.sched_priority = prio;

if (sched_setscheduler(0, SCHED_FIFO, &sparams) != 0) {
std::cerr << "[oals::rt] set_thread_realtime failed" << std::endl;
}
}
void set_running_cpu(int cpu_id) {
cpu_set_t cs{};
CPU_ZERO(&cs);
CPU_SET(cpu_id, &cs);

if (sched_setaffinity(0, sizeof(cpu_set_t), &cs) != 0) {
std::cerr << "[oals::rt] set_running_cpu failed" << std::endl;
}
}

void set_process_scheduler_rr(int prio) {
sched_param params{};
params.sched_priority = prio;
if (sched_setscheduler(0, SCHED_RR, &params) != 0) {
std::cerr << "[oals::rt] set_process_scheduler_rr failed" << std::endl;
}
}

void precise_sleep(long ns) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit of sleep time should be seen explicitly. Maybe, change its name to something like precise_sleep_ns(...)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense!

timespec ts{};
ts.tv_sec = ns / 1'000'000'000;
ts.tv_nsec = ns % 1'000'000'000;
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, nullptr);
}


#else
void set_thread_realtime(uint8_t) {
}

void set_running_cpu(int) {
}

void set_process_scheduler_rr(int) {
}

void precise_sleep(long ns) {
timespec ts{};
ts.tv_sec = ns / 1'000'000'000;
ts.tv_nsec = ns % 1'000'000'000;
nanosleep(&ts, nullptr);
}
#endif
}
20 changes: 20 additions & 0 deletions netutils/rt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This file is part of the Open Audio Live System project, a live audio environment
// Copyright (c) 2026 - Jonathan D Reichardt
//
// This project is distributed under the Creative Commons CC-BY-NC-SA licence. https://creativecommons.org/licenses/by-nc-sa/4.0


#ifndef OPENAUDIONETWORK_RT_H
#define OPENAUDIONETWORK_RT_H
#include <cstdint>


namespace oals::rt {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More a "me" thing than a general rule. I like to limit namespace depth for the sake of concision.
Here it is not a problem, but I let you imagine that things like oals::clocking::sync::ClockSync can start to look heavy (and also that would lead to heavy use of using namespace xxx which I think doesn't help that much in terms of clarity).

I probably would've called the namespace rt or rt_shim, as the oals is not used anywhere else.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah ok, i see! Makes sense!
The java dev in me would like to see oals::clocking::sync::ClockSync though.
Just kidding.

I was thinking olas::... because its not a network or other specific functionality, but more a helper across the whole system.

But I'm also ok renaming it to just rt.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking olas::... because its not a network or other specific functionality, but more a helper across the whole system.

Fair point. Haven't seen it that way. I think you're right. Let's keep oals::rt

void set_thread_realtime(uint8_t);
void set_running_cpu(int);
void set_process_scheduler_rr(int);
void precise_sleep(long);
}


#endif //OPENAUDIONETWORK_RT_H
Loading