1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:07:47 +00:00

Kernel/LibC: Implement sched_* functionality to set/get process priority

Right now, we allow anything inside a user to raise or lower any other process's
priority. This feels simple enough to me. Linux disallows raising, but
that's annoying in practice.
This commit is contained in:
Robin Burchell 2019-05-29 23:20:51 +02:00 committed by Andreas Kling
parent b160677e9e
commit 9cd0f6ffac
8 changed files with 103 additions and 1 deletions

View file

@ -2282,6 +2282,49 @@ int Process::sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen)
return 0;
}
int Process::sys$sched_setparam(pid_t pid, const struct sched_param* param)
{
if (!validate_read_typed(param))
return -EFAULT;
InterruptDisabler disabler;
auto* peer = this;
if (pid != 0)
peer = Process::from_pid(pid);
if (!peer)
return -ESRCH;
if (!is_superuser() && m_euid != peer->m_uid && m_uid != peer->m_uid)
return -EPERM;
if (param->sched_priority < Process::FirstPriority || param->sched_priority > Process::LastPriority)
return -EINVAL;
peer->set_priority(Priority(param->sched_priority));
return 0;
}
int Process::sys$sched_getparam(pid_t pid, struct sched_param* param)
{
if (!validate_read_typed(param))
return -EFAULT;
InterruptDisabler disabler;
auto* peer = this;
if (pid != 0)
peer = Process::from_pid(pid);
if (!peer)
return -ESRCH;
if (!is_superuser() && m_euid != peer->m_uid && m_uid != peer->m_uid)
return -EPERM;
param->sched_priority = peer->priority();
return 0;
}
int Process::sys$getsockopt(const Syscall::SC_getsockopt_params* params)
{
if (!validate_read_typed(params))

View file

@ -40,9 +40,11 @@ public:
enum Priority
{
IdlePriority,
FirstPriority = IdlePriority,
LowPriority,
NormalPriority,
HighPriority,
LastPriority = HighPriority,
};
enum RingLevel
@ -186,6 +188,8 @@ public:
int sys$setsockopt(const Syscall::SC_setsockopt_params*);
int sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen);
int sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen);
int sys$sched_setparam(pid_t pid, const struct sched_param* param);
int sys$sched_getparam(pid_t pid, struct sched_param* param);
int sys$restore_signal_mask(dword mask);
int sys$create_thread(int (*)(void*), void*);
void sys$exit_thread(int code);

View file

@ -276,6 +276,10 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
return current->process().sys$getsockname((int)arg1, (sockaddr*)arg2, (socklen_t*)arg3);
case Syscall::SC_getpeername:
return current->process().sys$getpeername((int)arg1, (sockaddr*)arg2, (socklen_t*)arg3);
case Syscall::SC_sched_setparam:
return current->process().sys$sched_setparam((pid_t)arg1, (struct sched_param*)arg2);
case Syscall::SC_sched_getparam:
return current->process().sys$sched_setparam((pid_t)arg1, (struct sched_param*)arg2);
default:
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
return -ENOSYS;

View file

@ -105,7 +105,9 @@
__ENUMERATE_SYSCALL(writev) \
__ENUMERATE_SYSCALL(beep) \
__ENUMERATE_SYSCALL(getsockname) \
__ENUMERATE_SYSCALL(getpeername)
__ENUMERATE_SYSCALL(getpeername) \
__ENUMERATE_SYSCALL(sched_setparam) \
__ENUMERATE_SYSCALL(sched_getparam)
namespace Syscall {

View file

@ -400,3 +400,7 @@ struct iovec {
void* iov_base;
size_t iov_len;
};
struct sched_param {
int sched_priority;
};

View file

@ -10,5 +10,29 @@ int sched_yield()
__RETURN_WITH_ERRNO(rc, rc, -1);
}
int sched_get_priority_min(int policy)
{
(void)policy;
return 0; // Idle
}
int sched_get_priority_max(int policy)
{
(void)policy;
return 3; // High
}
int sched_setparam(pid_t pid, const struct sched_param *param)
{
int rc = syscall(SC_sched_setparam, pid, param);
__RETURN_WITH_ERRNO(rc, rc, -1);
}
int sched_getparam(pid_t pid, struct sched_param *param)
{
int rc = syscall(SC_sched_getparam, pid, param);
__RETURN_WITH_ERRNO(rc, rc, -1);
}
}

View file

@ -1,9 +1,24 @@
#pragma once
#include <sys/types.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
int sched_yield();
struct sched_param {
int sched_priority;
};
#define SCHED_FIFO 0
#define SCHED_RR 1
#define SCHED_OTHER 2
#define SCHED_BATCH 3
int sched_get_priority_min(int policy);
int sched_get_priority_max(int policy);
int sched_setparam(pid_t pid, const struct sched_param *param);
int sched_getparam(pid_t pid, struct sched_param *param);
__END_DECLS

View file

@ -107,4 +107,10 @@ enum
#define X_OK 1
#define F_OK 0
/*
* We aren't fully compliant (don't support policies, and don't have a wide
* range of values), but we do have process priorities.
*/
#define _POSIX_PRIORITY_SCHEDULING
__END_DECLS