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.
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)
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)
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)
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)
{
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:
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;
};
_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
realpath.c \
rindex.c \
rlimit.c \
+ rss_nice.c \
setenv.c \
setmode.c \
settimeofday.c \
--- /dev/null
+#define _SYSTEM 1
+
+#include <assert.h>
+#include <errno.h>
+#include <minix/com.h>
+#include <minix/config.h>
+#include <minix/const.h>
+#include <minix/ipc.h>
+#include <minix/rs.h>
+#include <minix/type.h>
+#include <stdlib.h>
+#include <timers.h>
+#include <unistd.h>
+
+#include <machine/archtypes.h>
+#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;
+}
}
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)
{
*===========================================================================*/
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;
}