Skip to content

Commit eb84d4b

Browse files
committed
harden runtime and config
1 parent 827903d commit eb84d4b

9 files changed

Lines changed: 57 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
- Improved `ZeroHttpPump` and `ZeroMqttPump` throughput by allowing bounded intra-tick progress.
1111
- Added `ZEROKERNEL_PROFILE_LEAN_NET` for tighter network-oriented builds.
1212
- Reduced network module state again by compacting transport metrics counters.
13+
- Hardened config validation with compile-time capacity guards and conflicting-flag checks.
14+
- Copied task names into internal storage to avoid dangling name pointers.
15+
- Replaced Xtensa platform idle hint from a no-op with a real idle instruction.
1316

1417
## 1.3.x
1518

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,8 @@ Important lean-build switches:
459459

460460
`ZEROKERNEL_PROFILE_NETWORK_NODE` biases the runtime toward WiFi/BLE/MQTT-style firmware: key-first routing, bounded command/work queues, stronger drain budgets, and leaner metadata by default.
461461
`ZEROKERNEL_PROFILE_LEAN_NET` pushes harder on that same direction for module-heavy nodes: smaller queue defaults, stripped diagnostics, topic-key routing, and tighter runtime state for optional network helpers.
462+
- `ZEROKERNEL_PROFILE_TINY` now also defaults to key-first routing and stripped extended task metrics, so the name better matches the footprint target.
463+
- `ZEROKERNEL_PROFILE_NETWORK_NODE` now keeps capability gating enabled, which aligns the profile with network-aware runtime supervision.
462464
- `ZEROKERNEL_ENABLE_DEBUG_DUMP`
463465

464466
For small builds, the goal is to preserve the public API while collapsing runtime cost toward key-based routing and stripped diagnostics.

src/ZeroKernel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ class Kernel {
410410

411411
struct TaskSlot {
412412
TaskCallback callback;
413-
const char* name;
413+
char name[kTaskNameLength];
414414
TimeMs intervalMs;
415415
TimeMs maxRuntimeMs;
416416
TimeMs heartbeatTimeoutMs;

src/ZeroKernelConfig.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
#define ZEROKERNEL_DEFAULT_ENABLE_EVENT_COALESCING 1
2424
#define ZEROKERNEL_DEFAULT_ENABLE_COMMAND_QUEUE 1
2525
#define ZEROKERNEL_DEFAULT_ENABLE_WORK_QUEUE 1
26-
#define ZEROKERNEL_DEFAULT_ENABLE_LEGACY_LABEL_API 1
27-
#define ZEROKERNEL_DEFAULT_ENABLE_TOPIC_KEY_ONLY 0
26+
#define ZEROKERNEL_DEFAULT_ENABLE_LEGACY_LABEL_API 0
27+
#define ZEROKERNEL_DEFAULT_ENABLE_TOPIC_KEY_ONLY 1
2828
#define ZEROKERNEL_DEFAULT_ENABLE_TRACE 1
2929
#define ZEROKERNEL_DEFAULT_ENABLE_DIAGNOSTICS 0
3030
#define ZEROKERNEL_DEFAULT_ENABLE_DEBUG_DUMP 1
3131
#define ZEROKERNEL_DEFAULT_ENABLE_ADAPTIVE_DRAIN 1
3232
#define ZEROKERNEL_DEFAULT_ENABLE_SIGNAL_HOOK 0
33-
#define ZEROKERNEL_DEFAULT_ENABLE_EXTENDED_TASK_METRICS 1
33+
#define ZEROKERNEL_DEFAULT_ENABLE_EXTENDED_TASK_METRICS 0
3434
#define ZEROKERNEL_DEFAULT_ENABLE_CAPABILITIES 0
3535
#define ZEROKERNEL_DEFAULT_EVENT_QUEUE_BACKPRESSURE 1
3636
#define ZEROKERNEL_DEFAULT_COMMAND_QUEUE_BACKPRESSURE 1
@@ -143,7 +143,7 @@
143143
#define ZEROKERNEL_DEFAULT_ENABLE_ADAPTIVE_DRAIN 1
144144
#define ZEROKERNEL_DEFAULT_ENABLE_SIGNAL_HOOK 0
145145
#define ZEROKERNEL_DEFAULT_ENABLE_EXTENDED_TASK_METRICS 0
146-
#define ZEROKERNEL_DEFAULT_ENABLE_CAPABILITIES 0
146+
#define ZEROKERNEL_DEFAULT_ENABLE_CAPABILITIES 1
147147
#define ZEROKERNEL_DEFAULT_EVENT_QUEUE_BACKPRESSURE 1
148148
#define ZEROKERNEL_DEFAULT_COMMAND_QUEUE_BACKPRESSURE 1
149149
#define ZEROKERNEL_DEFAULT_WORK_QUEUE_BACKPRESSURE 1
@@ -376,4 +376,22 @@
376376
#define ZEROKERNEL_WORK_QUEUE_BACKPRESSURE ZEROKERNEL_DEFAULT_WORK_QUEUE_BACKPRESSURE
377377
#endif
378378

379+
#if ZEROKERNEL_ENABLE_TOPIC_KEY_ONLY && ZEROKERNEL_ENABLE_LEGACY_LABEL_API
380+
#error "ZEROKERNEL_ENABLE_TOPIC_KEY_ONLY and ZEROKERNEL_ENABLE_LEGACY_LABEL_API cannot both be enabled"
381+
#endif
382+
383+
#if defined(__cplusplus)
384+
static_assert(ZEROKERNEL_MAX_TASKS <= 255, "ZEROKERNEL_MAX_TASKS exceeds uint8_t storage");
385+
static_assert(ZEROKERNEL_MAX_SUBSCRIBERS <= 255, "ZEROKERNEL_MAX_SUBSCRIBERS exceeds uint8_t storage");
386+
static_assert(ZEROKERNEL_MAX_TYPED_SUBSCRIBERS <= 255,
387+
"ZEROKERNEL_MAX_TYPED_SUBSCRIBERS exceeds uint8_t storage");
388+
static_assert(ZEROKERNEL_MAX_EVENT_QUEUE <= 255, "ZEROKERNEL_MAX_EVENT_QUEUE exceeds uint8_t storage");
389+
static_assert(ZEROKERNEL_MAX_COMMAND_HANDLERS <= 255,
390+
"ZEROKERNEL_MAX_COMMAND_HANDLERS exceeds uint8_t storage");
391+
static_assert(ZEROKERNEL_MAX_COMMAND_QUEUE <= 255,
392+
"ZEROKERNEL_MAX_COMMAND_QUEUE exceeds uint8_t storage");
393+
static_assert(ZEROKERNEL_MAX_WORK_QUEUE <= 255, "ZEROKERNEL_MAX_WORK_QUEUE exceeds uint8_t storage");
394+
static_assert(ZEROKERNEL_MAX_TRACE_ENTRIES <= 255, "ZEROKERNEL_MAX_TRACE_ENTRIES exceeds uint8_t storage");
395+
#endif
396+
379397
#endif

src/core/KernelRuntime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void Kernel::begin(ClockSource clockSource) {
8888
resetCommandQueue_();
8989
resetWorkQueue_();
9090
resetTrace_();
91-
eventFlags_ = 0;
91+
internal::atomicStoreU32(&eventFlags_, 0);
9292
lastPanic_ = PanicInfo();
9393
safeMode_ = false;
9494
safeModePriorityFloor_ = kPriorityHigh;

src/core/Watchdog.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void Kernel::initializeTaskSlot_(TaskSlot& slot,
166166
slot = TaskSlot();
167167
slot.inUse = true;
168168
slot.startEnabled = config.startEnabled;
169-
slot.name = config.name;
169+
copyLabel_(slot.name, sizeof(slot.name), config.name);
170170
slot.callback = config.callback;
171171
slot.intervalMs = config.intervalMs;
172172
slot.maxRuntimeMs = config.maxRuntimeMs;
@@ -347,6 +347,7 @@ bool Kernel::isTaskDue_(const TaskSlot& slot, TimeMs nowMs) const {
347347
return false;
348348
}
349349

350+
// Unsigned subtraction keeps due checks stable across millis() wrap-around.
350351
return (nowMs - slot.lastRunAtMs) >= slot.intervalMs;
351352
}
352353

src/internal/KernelArch.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ inline uint32_t atomicLoadU32(const volatile uint32_t* target) {
2020
#endif
2121
}
2222

23+
inline void atomicStoreU32(volatile uint32_t* target, uint32_t value) {
24+
#if defined(__GNUC__) || defined(__clang__)
25+
__atomic_store_n(target, value, __ATOMIC_RELAXED);
26+
#else
27+
*target = value;
28+
#endif
29+
}
30+
2331
inline uint32_t atomicOrU32(volatile uint32_t* target, uint32_t mask) {
2432
#if defined(__GNUC__) || defined(__clang__)
2533
return __atomic_fetch_or(target, mask, __ATOMIC_RELAXED);

src/internal/KernelArchAsm.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
.text
33
.global zk_arch_idle_hint_asm
44
zk_arch_idle_hint_asm:
5-
nop
5+
waiti 0
66
#if defined(__XTENSA_WINDOWED_ABI__)
77
retw.n
88
#else

tests/desktop/KernelTests.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,22 @@ int testTaskScheduling() {
444444
return g_failures;
445445
}
446446

447+
int testTaskNameCopy() {
448+
zerokernel::Kernel isolatedKernel;
449+
char mutableName[24] = "MutableTask";
450+
451+
expectTrue(isolatedKernel.addTask(mutableName, periodicTask, 25, 0), "add mutable-name task");
452+
mutableName[0] = 'X';
453+
454+
zerokernel::Kernel::TaskStats stats;
455+
expectTrue(isolatedKernel.getTaskStats("MutableTask", stats),
456+
"task lookup still works after source buffer changes");
457+
expectTrue(stats.name[0] == 'M', "stored task name is copied into kernel storage");
458+
expectTrue(!isolatedKernel.getTaskStats("XutableTask", stats),
459+
"mutating source buffer does not rename stored task");
460+
return g_failures;
461+
}
462+
447463
int testNextWakeHint() {
448464
zerokernel::Kernel isolatedKernel;
449465
expectTrue(isolatedKernel.addTask("Wake", periodicTask, 50, 0), "add wake task");
@@ -1124,6 +1140,7 @@ int main() {
11241140
testEventFlags();
11251141
testHeartbeatTimeout();
11261142
testTaskScheduling();
1143+
testTaskNameCopy();
11271144
testNextWakeHint();
11281145
testPriorityScheduling();
11291146
testSafeMode();

0 commit comments

Comments
 (0)