menios
menios copied to clipboard
clock_nanosleep() and timerfd support
Goal
Implement clock_nanosleep() syscall and timerfd mechanisms for event-driven time waits.
Context
Only POSIX nanosleep() exists; clock_nanosleep() variant is missing (src/kernel/syscall/syscall.c has no handler). This limits sleep to CLOCK_REALTIME and prevents absolute time sleeps.
Current State
- ✅ nanosleep() implemented (#287)
- ❌ clock_nanosleep() missing
- ❌ No timerfd support for event-driven waits
What's Needed
1. clock_nanosleep() Syscall
// SYS_clock_nanosleep - Sleep on specific clock
// int clock_nanosleep(clockid_t clk_id, int flags,
// const struct timespec *req, struct timespec *rem)
long sys_clock_nanosleep(clockid_t clk_id, int flags,
const struct timespec *req, struct timespec *rem);
// Flags
#define TIMER_ABSTIME 1 // Absolute time (vs relative)
Features:
- Support CLOCK_REALTIME, CLOCK_MONOTONIC
- TIMER_ABSTIME flag for absolute sleep deadlines
- Return remaining time if interrupted
- Proper error codes (EINVAL for bad clock, EINTR if interrupted)
2. timerfd Support
// Create timer file descriptor
int timerfd_create(int clockid, int flags);
// Set timer
int timerfd_settime(int fd, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value);
// Get timer
int timerfd_gettime(int fd, struct itimerspec *curr_value);
Features:
- Timer as a file descriptor (pollable, epoll-able)
- One-shot and periodic timers
- Read returns number of expirations
- TFD_NONBLOCK and TFD_CLOEXEC flags
Implementation Strategy
Phase 1: clock_nanosleep()
- Add SYS_CLOCK_NANOSLEEP to syscall table
- Implement sys_clock_nanosleep() handler
- Extend sleep queue to track clock source
- Support absolute vs relative time
- Add libc wrapper
Phase 2: timerfd
- Create timerfd file operations
- Implement timerfd_create() syscall
- Implement timerfd_settime()/gettime()
- Integrate with file descriptor table
- Support poll/select on timerfd
- Add libc wrappers
Files to Create/Modify
- src/kernel/syscall/syscall.c - Add clock_nanosleep handler
- src/kernel/time/sleep.c - Extend sleep queue for multiple clocks
- src/kernel/fs/timerfd.c (new) - timerfd implementation
- include/sys/timerfd.h (new) - timerfd userspace API
- libc/src/time/clock_nanosleep.c (new)
- test/test_clock_nanosleep.c (new)
- test/test_timerfd.c (new)
Usage Examples
clock_nanosleep() absolute time
#include <time.h>
// Sleep until absolute time
struct timespec deadline;
clock_gettime(CLOCK_MONOTONIC, &deadline);
deadline.tv_sec += 5; // 5 seconds from now
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL);
timerfd periodic timer
#include <sys/timerfd.h>
int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
struct itimerspec timer;
timer.it_value.tv_sec = 1; // Initial expiration: 1 second
timer.it_value.tv_nsec = 0;
timer.it_interval.tv_sec = 1; // Repeat every 1 second
timer.it_interval.tv_nsec = 0;
timerfd_settime(tfd, 0, &timer, NULL);
uint64_t expirations;
while (read(tfd, &expirations, sizeof(expirations)) > 0) {
printf("Timer fired %llu times\n", expirations);
}
Testing
- Absolute time sleep with TIMER_ABSTIME
- clock_nanosleep() with different clocks
- timerfd one-shot timers
- timerfd periodic timers
- timerfd with poll/select
- Edge cases: past deadline, zero timeout
- Interrupted sleep handling
Dependencies
- #287 - nanosleep() and sleep queue (✅ complete)
- #326 - Centralized timekeeper (new)
- #96 - File descriptor management (✅ complete)
Parent Issue
- #226 - RTC and time management