From 37325bd7c5fa3aa99a1b690a62e070980c8b3e84 Mon Sep 17 00:00:00 2001 From: Erik van der Kouwe Date: Sat, 3 Jul 2010 05:02:59 +0000 Subject: [PATCH] Make service ABI backwards compatible again --- commands/service/service.c | 24 ++++++---- include/minix/rs.h | 8 ++-- lib/libc/other/Makefile.inc | 1 + lib/libc/other/rss_nice.c | 88 +++++++++++++++++++++++++++++++++++++ servers/rs/manager.c | 6 +-- servers/rs/request.c | 24 ++++++---- 6 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 lib/libc/other/rss_nice.c diff --git a/commands/service/service.c b/commands/service/service.c index bfd7431e0..59c13bf51 100644 --- a/commands/service/service.c +++ b/commands/service/service.c @@ -123,6 +123,9 @@ PRIVATE int req_lu_maxtime = DEFAULT_LU_MAXTIME; PRIVATE char command[4096]; /* Arguments for RS to start a new service */ +PRIVATE endpoint_t rss_scheduler; +PRIVATE unsigned rss_priority; +PRIVATE unsigned rss_quantum; PRIVATE struct rs_start rs_start; /* An error occurred. Report the problem, print the usage, and exit. @@ -567,7 +570,7 @@ PRIVATE void do_scheduler(config_t *cpe) fatal("do_scheduler: scheduler %d out of range at %s:%d", scheduler_val, cpe->file, cpe->line); } - rs_start.rss_scheduler= (endpoint_t) scheduler_val; + rss_scheduler= (endpoint_t) scheduler_val; } PRIVATE void do_priority(config_t *cpe) @@ -605,7 +608,7 @@ PRIVATE void do_priority(config_t *cpe) fatal("do_priority: priority %d out of range at %s:%d", priority_val, cpe->file, cpe->line); } - rs_start.rss_priority= (unsigned) priority_val; + rss_priority= (unsigned) priority_val; } PRIVATE void do_quantum(config_t *cpe) @@ -643,7 +646,7 @@ PRIVATE void do_quantum(config_t *cpe) fatal("do_quantum: quantum %d out of range at %s:%d", quantum_val, cpe->file, cpe->line); } - rs_start.rss_quantum= (unsigned) quantum_val; + rss_quantum= (unsigned) quantum_val; } PRIVATE void do_irq(config_t *cpe) @@ -1217,14 +1220,21 @@ PUBLIC int main(int argc, char **argv) fatal("no passwd file entry for '%s'", SERVICE_LOGIN); rs_start.rss_uid= pw->pw_uid; - rs_start.rss_scheduler= SCHED_PROC_NR; - rs_start.rss_priority= USER_Q; - rs_start.rss_quantum= 200; + rss_scheduler= SCHED_PROC_NR; + rss_priority= USER_Q; + rss_quantum= 200; if (req_config) { assert(progname); do_config(progname, req_config); } + assert(rss_priority < NR_SCHED_QUEUES); + assert(rss_quantum > 0); + if (rss_nice_encode(&rs_start.rss_nice, rss_scheduler, + rss_priority, rss_quantum) != OK) { + fatal("cannot encode scheduling parameters %d, %u, %u", + rss_scheduler, rss_priority, rss_quantum); + } if (req_ipc) { @@ -1237,8 +1247,6 @@ PUBLIC int main(int argc, char **argv) rs_start.rss_ipclen= 0; } - assert(rs_start.rss_priority < NR_SCHED_QUEUES); - assert(rs_start.rss_quantum > 0); m.RS_CMD_ADDR = (char *) &rs_start; break; case RS_DOWN: diff --git a/include/minix/rs.h b/include/minix/rs.h index a124e6377..201192d3e 100644 --- a/include/minix/rs.h +++ b/include/minix/rs.h @@ -42,9 +42,7 @@ struct rs_start char *rss_cmd; size_t rss_cmdlen; uid_t rss_uid; - endpoint_t rss_scheduler; - unsigned rss_priority; - unsigned rss_quantum; + int rss_nice; /* use rss_nice_encode and _decode */ int rss_major; int rss_dev_style; long rss_period; @@ -99,5 +97,9 @@ struct rprocpub { }; _PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value)); +_PROTOTYPE(int rss_nice_encode, (int *nice, endpoint_t scheduler, + unsigned priority, unsigned quantum)); +_PROTOTYPE(int rss_nice_decode, (int nice, endpoint_t *scheduler, + unsigned *priority, unsigned *quantum)); #endif diff --git a/lib/libc/other/Makefile.inc b/lib/libc/other/Makefile.inc index 7f96f8ee4..e0394c5dc 100644 --- a/lib/libc/other/Makefile.inc +++ b/lib/libc/other/Makefile.inc @@ -88,6 +88,7 @@ SRCS+= \ realpath.c \ rindex.c \ rlimit.c \ + rss_nice.c \ setenv.c \ setmode.c \ settimeofday.c \ diff --git a/lib/libc/other/rss_nice.c b/lib/libc/other/rss_nice.c new file mode 100644 index 000000000..cb2363253 --- /dev/null +++ b/lib/libc/other/rss_nice.c @@ -0,0 +1,88 @@ +#define _SYSTEM 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../../../kernel/priv.h" +#include "../../../kernel/proc.h" + +#define SCHED_BITS 9 +#define PRIO_BITS 8 +#define QUANTUM_BITS 14 + +#define SCHED_SHIFT 0 +#define PRIO_SHIFT (SCHED_BITS + SCHED_SHIFT) +#define QUANTUM_SHIFT (PRIO_SHIFT + PRIO_BITS) +#define ABI_SHIFT (QUANTUM_SHIFT + QUANTUM_BITS) + +#define MAXU(bits) ((unsigned) ((1 << (bits)) - 1)) +#define MINS(bits) ((int) (-(1 << ((bits) - 1)))) +#define MAXS(bits) ((int) ((1 << ((bits) - 1)) - 1)) + +#define ENCODE(value, shift, bits) \ + ((((unsigned) (value)) & ((1 << (bits)) - 1)) << (shift)) +#define DECODE(value, shift, bits) \ + ((((unsigned) (value)) >> (shift)) & ((1 << (bits)) - 1)) + +PUBLIC int rss_nice_encode(int *nice, endpoint_t scheduler, + unsigned priority, unsigned quantum) +{ + unsigned scheduler_u; + + assert(ABI_SHIFT == 31); + + /* check whether values fit */ + if (!nice) return EINVAL; + *nice = 0; + scheduler_u = (unsigned) (scheduler + NR_TASKS); + if (scheduler_u > MAXU(SCHED_BITS)) return EINVAL; + if (priority > MAXU(PRIO_BITS)) return EINVAL; + if (quantum > MAXU(QUANTUM_BITS)) return EINVAL; + + /* encode */ + *nice = ENCODE(scheduler_u, SCHED_SHIFT, SCHED_BITS) | + ENCODE(priority, PRIO_SHIFT, PRIO_BITS) | + ENCODE(quantum, QUANTUM_SHIFT, QUANTUM_BITS) | + ENCODE(1, ABI_SHIFT, 1); + + return OK; +} + +PUBLIC int rss_nice_decode(int nice, endpoint_t *scheduler, + unsigned *priority, unsigned *quantum) +{ + unsigned scheduler_u; + + assert(ABI_SHIFT == 31); + + /* check arguments */ + if (!scheduler) return EINVAL; + if (!priority) return EINVAL; + if (!quantum) return EINVAL; + + /* accept either old or new ABI */ + if (nice & (1 << ABI_SHIFT)) { + /* new ABI, decode */ + scheduler_u = DECODE(nice, SCHED_SHIFT, SCHED_BITS); + *scheduler = (int) scheduler_u - NR_TASKS; + *priority = DECODE(nice, PRIO_SHIFT, PRIO_BITS); + *quantum = DECODE(nice, QUANTUM_SHIFT, QUANTUM_BITS); + } else { + /* old ABI, not useful so just take defaults */ + *scheduler = USER_SCH; + *priority = USER_Q; + *quantum = USER_QUANTUM; + } + + return OK; +} diff --git a/servers/rs/manager.c b/servers/rs/manager.c index a13dfe5d8..3af8f10a6 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -1281,9 +1281,9 @@ endpoint_t source; } rp->r_uid= rs_start->rss_uid; - rp->r_scheduler= rs_start->rss_scheduler; - rp->r_priority= rs_start->rss_priority; - rp->r_quantum= rs_start->rss_quantum; + s = rss_nice_decode(rs_start->rss_nice, &rp->r_scheduler, + &rp->r_priority, &rp->r_quantum); + if (s != OK) return(s); if (rs_start->rss_flags & RSS_IPC_VALID) { diff --git a/servers/rs/request.c b/servers/rs/request.c index 3bf330a4d..ba40ee702 100755 --- a/servers/rs/request.c +++ b/servers/rs/request.c @@ -787,22 +787,30 @@ message *m_ptr; *===========================================================================*/ PRIVATE int check_request(struct rs_start *rs_start) { + int s; + endpoint_t rss_scheduler; + unsigned rss_priority, rss_quantum; + + s = rss_nice_decode(rs_start->rss_nice, &rss_scheduler, + &rss_priority, &rss_quantum); + if (s != OK) return s; + /* Verify scheduling parameters */ - if (rs_start->rss_scheduler != KERNEL && - (rs_start->rss_scheduler < 0 || - rs_start->rss_scheduler > LAST_SPECIAL_PROC_NR)) { + if (rss_scheduler != KERNEL && + (rss_scheduler < 0 || + rss_scheduler > LAST_SPECIAL_PROC_NR)) { printf("RS: check_request: invalid scheduler %d\n", - rs_start->rss_scheduler); + rss_scheduler); return EINVAL; } - if (rs_start->rss_priority >= NR_SCHED_QUEUES) { + if (rss_priority >= NR_SCHED_QUEUES) { printf("RS: check_request: priority %u out of range\n", - rs_start->rss_priority); + rss_priority); return EINVAL; } - if (rs_start->rss_quantum <= 0) { + if (rss_quantum <= 0) { printf("RS: check_request: quantum %u out of range\n", - rs_start->rss_quantum); + rss_quantum); return EINVAL; } -- 2.44.0