/* To get syscall() we need to define _GNU_SOURCE * in modern glibc versions. */ /* imported from the kernel source tree */ #include "asm/unistd.h" /* for syscall() */ #include #include "litmus.h" #include "internal.h" /* handling GPU-budget enforcement */ #include #include /* Syscall stub for setting RT mode and scheduling options */ // SUPER HACKY FIX THIS __thread lt_t enforcement_time; pid_t gettid(void) { return syscall(__NR_gettid); } int set_rt_task_param(pid_t pid, struct rt_task *param) { union litmus_syscall_args args; args.get_set_task_param.pid = pid; args.get_set_task_param.param = param; return litmus_syscall(LRT_set_rt_task_param, (unsigned long) &args); } int get_rt_task_param(pid_t pid, struct rt_task *param) { union litmus_syscall_args args; args.get_set_task_param.pid = pid; args.get_set_task_param.param = param; return litmus_syscall(LRT_get_rt_task_param, (unsigned long) &args); } int reservation_create(int rtype, void *config) { union litmus_syscall_args args; args.reservation_create.type = rtype; args.reservation_create.config = config; return litmus_syscall(LRT_reservation_create, (unsigned long) &args); } int sleep_next_period(void) { return litmus_syscall(LRT_complete_job, 0); } int od_openx(int fd, obj_type_t type, int obj_id, void *config) { union litmus_syscall_args args; args.od_open.fd = fd; args.od_open.obj_type = type; args.od_open.obj_id = obj_id; args.od_open.config = config; return litmus_syscall(LRT_od_open, (unsigned long) &args); } int od_close(int od) { return litmus_syscall(LRT_od_close, od); } int litmus_lock(int od) { return litmus_syscall(LRT_litmus_lock, od); } int litmus_lock_cs(int od, lt_t cs_len) { union litmus_syscall_args args; args.litmus_lock_cs.sem_od = od; args.litmus_lock_cs.cs_len = cs_len; return litmus_syscall(LRT_litmus_lock_cs, (unsigned long) &args); } int litmus_access_forbidden_zone_check(int od, lt_t fz_len, lt_t panic_len) { int ret; union litmus_syscall_args args; args.access_forbidden_zone_check.sem_od = od; args.access_forbidden_zone_check.fz_len = fz_len; args.access_forbidden_zone_check.panic_len = panic_len; ret = litmus_syscall(LRT_access_forbidden_zone_check, (unsigned long) &args); // Set the time that the access must complete by to avoid budget enforcement assert(fz_len >= panic_len); enforcement_time = litmus_clock() + fz_len; return ret; } int litmus_set_fz_launch_done(int od) { // Call the exit_forbidden_zone litmus call to cancel the timer return litmus_syscall(LRT_cancel_watchdog, od); } int litmus_exit_forbidden_zone(int od) { // If the current time is later than the enforcement time, // send a signal if (litmus_clock() > enforcement_time) { raise(SIGSYS); } return 0; } int litmus_unlock(int od) { return litmus_syscall(LRT_litmus_unlock, od); } int get_job_no(unsigned int *job_no) { struct control_page* cp = get_ctrl_page(); if (likely(cp != NULL)) { *job_no = cp->job_index; return 0; } else { return -1; } } int wait_for_job_release(unsigned int job_no) { return litmus_syscall(LRT_wait_for_job_release, job_no); } int wait_for_ts_release(void) { return litmus_syscall(LRT_wait_for_ts_release, 0); } int release_ts(lt_t *when) { return litmus_syscall(LRT_release_ts, (unsigned long) when); } int null_call(cycles_t *timestamp) { return litmus_syscall(LRT_null_call, (unsigned long) timestamp); } int get_current_budget( lt_t *expended, lt_t *remaining) { union litmus_syscall_args args; args.get_current_budget.expended = expended; args.get_current_budget.remaining = remaining; return litmus_syscall(LRT_get_current_budget, (unsigned long) &args); }