commit df4284d616b4107ac680852d82812da74c56da6e
parent 3a6d409e84e13fba8972da4c641e8b52b06822de
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 5 Apr 2021 11:54:13 -0400
unix: add nice
Diffstat:
5 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -575,3 +575,13 @@ export fn getresgid(gid: *gid_t, egid: *gid_t, sgid: *gid_t) (void | errno) = {
sgid: uintptr: u64))?;
return;
};
+
+export fn getpriority(which: int, who: id_t) (int | errno) = {
+ return wrap_return(syscall2(SYS_setpriority,
+ which: u64, who: u64))?: int;
+};
+
+export fn setpriority(which: int, who: id_t, prio: int) (void | errno) = {
+ wrap_return(syscall3(SYS_setpriority, which: u64, who: u64, prio: u64))?;
+ return;
+};
diff --git a/rt/+linux/types.ha b/rt/+linux/types.ha
@@ -3,6 +3,7 @@ export type dev_t = u64;
export type ino_t = u64;
export type nlink_t = u64;
export type mode_t = uint;
+export type id_t = uint;
export type uid_t = uint;
export type gid_t = uint;
export type time_t = i64;
@@ -551,3 +552,7 @@ export type cmsg = struct {
hdr: cmsghdr,
cmsg_data: [*]u8,
};
+
+export def PRIO_PROCESS: int = 0;
+export def PRIO_PGRP: int = 1;
+export def PRIO_USER: int = 2;
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -571,7 +571,9 @@ unicode() {
}
unix() {
+ # XXX: getuid and setuid are probably platform-specific too
gen_srcs unix \
+ nice'$(PLATFORM)'.ha \
getuid.ha \
setuid.ha
gen_ssa unix
diff --git a/stdlib.mk b/stdlib.mk
@@ -762,6 +762,7 @@ $(HARECACHE)/unicode/unicode.ssa: $(stdlib_unicode_srcs) $(stdlib_rt)
# unix
stdlib_unix_srcs= \
+ $(STDLIB)/unix/nice$(PLATFORM).ha \
$(STDLIB)/unix/getuid.ha \
$(STDLIB)/unix/setuid.ha
@@ -1569,6 +1570,7 @@ $(TESTCACHE)/unicode/unicode.ssa: $(testlib_unicode_srcs) $(testlib_rt)
# unix
testlib_unix_srcs= \
+ $(STDLIB)/unix/nice$(PLATFORM).ha \
$(STDLIB)/unix/getuid.ha \
$(STDLIB)/unix/setuid.ha
diff --git a/unix/nice+linux.ha b/unix/nice+linux.ha
@@ -0,0 +1,23 @@
+use errors;
+use rt;
+
+// Adds the argument to the niceness of the current process. The input should be
+// between -20 and 19 (inclusive); lower numbers represent a higher priority.
+// Generally, you must have elevated permissions to reduce your niceness, but
+// not to increase it.
+export fn nice(inc: int) (void | errors::opaque) = {
+ let prio = inc;
+ if (inc > -40 && inc <= 40) {
+ prio += rt::getpriority(rt::PRIO_PROCESS, 0) as int;
+ };
+ if (prio > 19) {
+ prio = 19;
+ };
+ if (prio < -20) {
+ prio = -20;
+ };
+ return match (rt::setpriority(rt::PRIO_PROCESS, 0, prio)) {
+ void => void,
+ err: rt::errno => errors::errno(err),
+ };
+};