diff --git a/libc/Makefile b/libc/Makefile
index 6c9e4c9b..38354c9e 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -308,6 +308,8 @@ sys/mman/mmap.o \
sys/mman/mprotect.o \
sys/mman/munmap.o \
sys/readdirents/readdirents.o \
+sys/resource/getpriority.o \
+sys/resource/setpriority.o \
sys/select/select.o \
sys/socket/accept4.o \
sys/socket/accept.o \
diff --git a/libc/include/sys/resource.h b/libc/include/sys/resource.h
new file mode 100644
index 00000000..e14dc32e
--- /dev/null
+++ b/libc/include/sys/resource.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ sys/resource.h
+ Resource limits and operations.
+
+*******************************************************************************/
+
+#ifndef INCLUDE_SYS_RESOURCE_H
+#define INCLUDE_SYS_RESOURCE_H
+
+#include
+#include
+
+__BEGIN_DECLS
+
+@include(id_t.h)
+
+int getpriority(int, id_t);
+int setpriority(int, id_t, int);
+
+__END_DECLS
+
+#endif
diff --git a/libc/sys/resource/getpriority.cpp b/libc/sys/resource/getpriority.cpp
new file mode 100644
index 00000000..5d8615d5
--- /dev/null
+++ b/libc/sys/resource/getpriority.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ sys/resource/getpriority.cpp
+ Get the scheduling priority of a process, process group, or user.
+
+*******************************************************************************/
+
+#include
+#include
+
+DEFN_SYSCALL2(int, sys_getpriority, SYSCALL_GETPRIORITY, int, id_t);
+
+extern "C" int getpriority(int which, id_t who)
+{
+ return sys_getpriority(which, who);
+}
diff --git a/libc/sys/resource/setpriority.cpp b/libc/sys/resource/setpriority.cpp
new file mode 100644
index 00000000..a63c30da
--- /dev/null
+++ b/libc/sys/resource/setpriority.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ sys/resource/setpriority.cpp
+ Set the scheduling priority of a process, process group, or user.
+
+*******************************************************************************/
+
+#include
+#include
+
+DEFN_SYSCALL3(int, sys_setpriority, SYSCALL_SETPRIORITY, int, id_t, int);
+
+extern "C" int setpriority(int which, id_t who, int prio)
+{
+ return sys_setpriority(which, who, prio);
+}
diff --git a/sortix/Makefile b/sortix/Makefile
index 8c1df59f..8564890c 100644
--- a/sortix/Makefile
+++ b/sortix/Makefile
@@ -116,6 +116,7 @@ pipe.o \
poll.o \
process.o \
refcount.o \
+resource.o \
scheduler.o \
segment.o \
serialterminal.o \
diff --git a/sortix/include/sortix/kernel/process.h b/sortix/include/sortix/kernel/process.h
index 8bb2010c..e8403d41 100644
--- a/sortix/include/sortix/kernel/process.h
+++ b/sortix/include/sortix/kernel/process.h
@@ -74,6 +74,10 @@ public:
addr_t addrspace;
pid_t pid;
+public:
+ kthread_mutex_t nicelock;
+ int nice;
+
public:
kthread_mutex_t idlock;
uid_t uid, euid;
diff --git a/sortix/include/sortix/resource.h b/sortix/include/sortix/resource.h
new file mode 100644
index 00000000..9adc821f
--- /dev/null
+++ b/sortix/include/sortix/resource.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ sortix/resource.h
+ Resource limits and operations.
+
+*******************************************************************************/
+
+#ifndef INCLUDE_SORTIX_RESOURCE_H
+#define INCLUDE_SORTIX_RESOURCE_H
+
+#include
+
+__BEGIN_DECLS
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP 1
+#define PRIO_USER 2
+
+__END_DECLS
+
+#endif
diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h
index 5d40a09d..3dbc5f07 100644
--- a/sortix/include/sortix/syscallnum.h
+++ b/sortix/include/sortix/syscallnum.h
@@ -140,6 +140,8 @@
#define SYSCALL_MMAP_WRAPPER 116
#define SYSCALL_MPROTECT 117
#define SYSCALL_MUNMAP 118
-#define SYSCALL_MAX_NUM 119 /* index of highest constant + 1 */
+#define SYSCALL_GETPRIORITY 119
+#define SYSCALL_SETPRIORITY 120
+#define SYSCALL_MAX_NUM 121 /* index of highest constant + 1 */
#endif
diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp
index 0db4ca5a..aba91fc1 100644
--- a/sortix/kernel.cpp
+++ b/sortix/kernel.cpp
@@ -73,6 +73,7 @@
#include "uart.h"
#include "logterminal.h"
#include "vgatextbuffer.h"
+#include "resource.h"
#include "serialterminal.h"
#include "textterminal.h"
#include "elf.h"
@@ -553,6 +554,9 @@ static void BootThread(void* /*user*/)
// Initialize the kernel information query syscall.
Info::Init();
+ // Initialize resource system calls.
+ Resource::Init();
+
// Initialize the Video Driver framework.
Video::Init(textbufhandle);
diff --git a/sortix/process.cpp b/sortix/process.cpp
index 6c6f764a..9106aba2 100644
--- a/sortix/process.cpp
+++ b/sortix/process.cpp
@@ -103,6 +103,8 @@ Process::Process()
uid = euid = 0;
gid = egid = 0;
umask = 0022;
+ nicelock = KTHREAD_MUTEX_INITIALIZER;
+ nice = 0;
Time::InitializeProcessClocks(this);
alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
Put(this);
@@ -647,6 +649,10 @@ Process* Process::Fork()
kthread_mutex_unlock(&groupchildlock);
// Initialize everything that is safe and can't fail.
+ kthread_mutex_lock(&nicelock);
+ clone->nice = nice;
+ kthread_mutex_unlock(&nicelock);
+
kthread_mutex_lock(&ptrlock);
clone->root = root;
clone->cwd = cwd;
diff --git a/sortix/resource.cpp b/sortix/resource.cpp
new file mode 100644
index 00000000..3b264032
--- /dev/null
+++ b/sortix/resource.cpp
@@ -0,0 +1,158 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of Sortix.
+
+ Sortix is free software: you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
+
+ resource.cpp
+ Resource limits and operations.
+
+*******************************************************************************/
+
+#include
+
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+#include "resource.h"
+
+namespace Sortix {
+namespace Resource {
+
+static int GetProcessPriority(pid_t who)
+{
+ if ( who < 0 )
+ return errno = EINVAL, -1;
+ // TODO: If who isn't the current process, then it could self-destruct at
+ // any time while we use it; there is no safe way to do this yet.
+ Process* process = who ? Process::Get(who) : CurrentProcess();
+ if ( !process )
+ return errno = ESRCH, -1;
+ ScopedLock lock(&process->nicelock);
+ return process->nice;
+}
+
+static int SetProcessPriority(pid_t who, int prio)
+{
+ if ( who < 0 )
+ return errno = EINVAL, -1;
+ // TODO: If who isn't the current process, then it could self-destruct at
+ // any time while we use it; there is no safe way to do this yet.
+ Process* process = who ? Process::Get(who) : CurrentProcess();
+ if ( !process )
+ return errno = ESRCH, -1;
+ ScopedLock lock(&process->nicelock);
+ process->nice = prio;
+ return 0;
+}
+
+static Process* CurrentProcessGroup()
+{
+ Process* process = CurrentProcess();
+ ScopedLock lock(&process->groupchildlock);
+ // TODO: The process group can change when this call returns, additionally
+ // the current process leader could self-destruct.
+ return process->group;
+}
+
+static int GetProcessGroupPriority(pid_t who)
+{
+ if ( who < 0 )
+ return errno = EINVAL, -1;
+ // TODO: If who isn't the current process, then it could self-destruct at
+ // any time while we use it; there is no safe way to do this yet.
+ Process* group = who ? Process::Get(who) : CurrentProcessGroup();
+ if ( !group )
+ return errno = ESRCH, -1;
+ int lowest = INT_MAX;
+ ScopedLock group_parent_lock(&group->groupparentlock);
+ for ( Process* process = group->groupfirst; process; process = process->groupnext )
+ {
+ ScopedLock lock(&process->nicelock);
+ if ( process->nice < lowest )
+ lowest = process->nice;
+ }
+ return lowest;
+}
+
+static int SetProcessGroupPriority(pid_t who, int prio)
+{
+ if ( who < 0 )
+ return errno = EINVAL, -1;
+ // TODO: If who isn't the current process, then it could self-destruct at
+ // any time while we use it; there is no safe way to do this yet.
+ Process* group = who ? Process::Get(who) : CurrentProcessGroup();
+ if ( !group )
+ return errno = ESRCH, -1;
+ ScopedLock group_parent_lock(&group->groupparentlock);
+ for ( Process* process = group->groupfirst; process; process = process->groupnext )
+ {
+ ScopedLock lock(&process->nicelock);
+ process->nice = prio;
+ }
+ return 0;
+}
+
+static int GetUserPriority(uid_t /*who*/)
+{
+ // TODO: There is currently no easy way to iterate all processes without
+ // dire race conditions being possible.
+ return errno = ENOSYS, -1;
+}
+
+static int SetUserPriority(uid_t /*who*/, int /*prio*/)
+{
+ // TODO: There is currently no easy way to iterate all processes without
+ // dire race conditions being possible.
+ return errno = ENOSYS, -1;
+}
+
+static int sys_getpriority(int which, id_t who)
+{
+ switch ( which )
+ {
+ case PRIO_PROCESS: return GetProcessPriority(who);
+ case PRIO_PGRP: return GetProcessGroupPriority(who);
+ case PRIO_USER: return GetUserPriority(who);
+ default: return errno = EINVAL, -1;
+ }
+}
+
+static int sys_setpriority(int which, id_t who, int prio)
+{
+ switch ( which )
+ {
+ case PRIO_PROCESS: return SetProcessPriority(who, prio);
+ case PRIO_PGRP: return SetProcessGroupPriority(who, prio);
+ case PRIO_USER: return SetUserPriority(who, prio);
+ default: return errno = EINVAL, -1;
+ }
+}
+
+void Init()
+{
+ Syscall::Register(SYSCALL_GETPRIORITY, (void*) sys_getpriority);
+ Syscall::Register(SYSCALL_SETPRIORITY, (void*) sys_setpriority);
+}
+
+} // namespace Resource
+} // namespace Sortix
diff --git a/sortix/resource.h b/sortix/resource.h
new file mode 100644
index 00000000..7648703b
--- /dev/null
+++ b/sortix/resource.h
@@ -0,0 +1,36 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of Sortix.
+
+ Sortix is free software: you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
+
+ resource.h
+ Resource limits and operations.
+
+*******************************************************************************/
+
+#ifndef SORTIX_RESOURCE_H
+#define SORTIX_RESOURCE_H
+
+namespace Sortix {
+namespace Resource {
+
+void Init();
+
+} // namespace Resource
+} // namespace Sortix
+
+#endif