Skip to content

Commit

Permalink
Implement SIGEV_THREAD_ID
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 3, 2023
1 parent 8f98de1 commit c99cb7b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
3 changes: 2 additions & 1 deletion kernel/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ void task_leave_session(struct task *task);
struct posix_timer {
struct timer *timer;
int_t timer_id;
struct task *task;
struct tgroup *tgroup;
pid_t_ thread_pid;
int_t signal;
union sigval_ sig_value;
};
Expand Down
34 changes: 23 additions & 11 deletions kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,20 @@ dword_t sys_settimeofday(addr_t UNUSED(tv), addr_t UNUSED(tz)) {
}

static void posix_timer_callback(struct posix_timer *timer) {
if (timer->task == NULL)
if (timer->tgroup == NULL)
return;
struct siginfo_ info = {
.code = SI_TIMER_,
.timer.timer = timer->timer_id,
.timer.overrun = 0,
.timer.value = timer->sig_value,
};
send_signal(timer->task, timer->signal, info);
lock(&pids_lock);
struct task *thread = pid_get_task(timer->thread_pid);
// TODO: solve pid reuse. currently we have two ways of referring to a task: pid_t_ and struct task *. pids get reused. task struct pointers get freed on exit or reap. need a third option for cases like this, like a refcount layer.
if (thread != NULL)
send_signal(thread, timer->signal, info);
unlock(&pids_lock);
}

#define SIGEV_SIGNAL_ 0
Expand All @@ -264,10 +269,16 @@ int_t sys_timer_create(dword_t clock, addr_t sigevent_addr, addr_t timer_addr) {
struct sigevent_ sigev;
if (user_get(sigevent_addr, sigev))
return _EFAULT;
// SIGEV_THREAD_ID_ is not supported yet
if (sigev.method != SIGEV_SIGNAL_ && sigev.method != SIGEV_NONE_)
if (sigev.method != SIGEV_SIGNAL_ && sigev.method != SIGEV_NONE_ && sigev.method != SIGEV_THREAD_ID_)
return _EINVAL;

if (sigev.method == SIGEV_THREAD_ID_) {
lock(&pids_lock);
if (pid_get_task(sigev.tid) == NULL)
return _EINVAL;
unlock(&pids_lock);
}

struct tgroup *group = current->group;
lock(&group->lock);
unsigned timer_id;
Expand All @@ -286,15 +297,16 @@ int_t sys_timer_create(dword_t clock, addr_t sigevent_addr, addr_t timer_addr) {

struct posix_timer *timer = &group->posix_timers[timer_id];
timer->timer_id = timer_id;

timer->timer = timer_new(real_clockid, (timer_callback_t) posix_timer_callback, timer);
timer->signal = sigev.signo;
timer->sig_value = sigev.value;
if (sigev.method == SIGEV_NONE_) {
timer->task = NULL;
} else if (sigev.method == SIGEV_SIGNAL_) {
timer->task = group->leader;
timer->signal = sigev.signo;
timer->sig_value = sigev.value;
timer->tgroup = NULL;
if (sigev.method == SIGEV_SIGNAL_) {
timer->tgroup = group;
timer->thread_pid = 0;
} else if (sigev.method == SIGEV_THREAD_ID_) {
timer->tgroup = group;
timer->thread_pid = group->leader->pid;
}
unlock(&group->lock);
return 0;
Expand Down

0 comments on commit c99cb7b

Please sign in to comment.