diff --git a/kernel/Makefile b/kernel/Makefile index 545e57be9..e973641f0 100755 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -17,7 +17,8 @@ HEAD = mpx.o OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \ i8259.o exception.o system.o clock.o misc.o SYS_OBJS = $s/proctl.o $s/copying.o $s/devio.o $s/sysctl.o $s/misc.o \ - $s/sigctl.o $s/tracing.o $s/clock.o $s/irqctl.o $s/debugging.o + $s/sigctl.o $s/tracing.o $s/clock.o $s/irqctl.o $s/debugging.o \ + $s/priority.o LIBS = -ltimers diff --git a/kernel/proc.c b/kernel/proc.c index e4424aa06..24399048f 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -525,7 +525,7 @@ struct proc *sched_ptr; /* quantum eating process */ unready(sched_ptr); /* remove from queues */ sched_ptr->p_priority ++; /* lower priority */ ready(sched_ptr); /* add to new queue */ -kprintf("Warning, proc %d got lower priority:\n", sched_ptr->p_nr); +kprintf("Warning, proc %d got lower priority: ", sched_ptr->p_nr); kprintf("%d\n", sched_ptr->p_priority); } sched_ptr->p_full_quantums = QUANTUMS(sched_ptr->p_priority); diff --git a/kernel/proc.h b/kernel/proc.h index 9437b97fe..eb7d8e74c 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -87,7 +87,7 @@ struct proc { #define NR_SCHED_QUEUES 16 /* MUST equal minimum priority + 1 */ #define TASK_Q 0 /* highest, reserved for kernel tasks */ #define MAX_USER_Q 8 /* highest priority for user processes */ -#define USER_Q 12 /* default priority for user processes */ +#define USER_Q 11 /* user default (should correspond to nice 0) */ #define MIN_USER_Q 14 /* minimum priority for user processes */ #define IDLE_Q 15 /* lowest, only IDLE process goes here */ diff --git a/kernel/system.c b/kernel/system.c index 39fddc4ff..2fd5613a4 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -163,6 +163,7 @@ PRIVATE void initialize(void) map(SYS_PHYSZERO, do_physzero); /* zero physical memory region */ map(SYS_VIRVCOPY, do_virvcopy); /* vector with copy requests */ map(SYS_PHYSVCOPY, do_physvcopy); /* vector with copy requests */ + map(SYS_SETPRIORITY, do_setpriority); /* set scheduling priority */ /* Miscellaneous. */ map(SYS_ABORT, do_abort); /* abort MINIX */ diff --git a/kernel/system.h b/kernel/system.h index d6339f2c0..3faeed6b1 100644 --- a/kernel/system.h +++ b/kernel/system.h @@ -46,6 +46,7 @@ _PROTOTYPE( int do_getsig, (message *m_ptr) ); _PROTOTYPE( int do_endsig, (message *m_ptr) ); _PROTOTYPE( int do_sigsend, (message *m_ptr) ); _PROTOTYPE( int do_sigreturn, (message *m_ptr) ); +_PROTOTYPE( int do_setpriority, (message *m_ptr) ); _PROTOTYPE( int do_times, (message *m_ptr) ); /* clock functions */ _PROTOTYPE( int do_setalarm, (message *m_ptr) ); diff --git a/kernel/system/Makefile b/kernel/system/Makefile index c08169584..498fe26aa 100644 --- a/kernel/system/Makefile +++ b/kernel/system/Makefile @@ -12,7 +12,7 @@ CFLAGS = -I$i LDFLAGS = -i SYS = clock.o copying.o debugging.o devio.o irqctl.o proctl.o \ - sysctl.o misc.o sigctl.o tracing.o + sysctl.o misc.o sigctl.o tracing.o priority.o # What to make. all build: $(SYS) diff --git a/kernel/system/priority.c b/kernel/system/priority.c new file mode 100644 index 000000000..33db5d5eb --- /dev/null +++ b/kernel/system/priority.c @@ -0,0 +1,56 @@ +/* The system call implemented in this file: + * m_type: SYS_SETPRIORITY + * + * The parameters for this system call are: + * m1_i1: which + * m1_i2: who + * m1_i3: prio + */ + +#include "../kernel.h" +#include "../system.h" +#include +#include + +/*===========================================================================* + * do_setpriority * + *===========================================================================*/ +PUBLIC int do_setpriority(message *m_ptr) +{ + int which_proc, pri, q, niceperq; + struct proc *which_procp; + + which_proc = m_ptr->m1_i1; + pri = m_ptr->m1_i2; + + /* pri is currently between PRIO_MIN and PRIO_MAX. We have to + * scale this between MIN_USER_Q and MAX_USER_Q. + */ + + if(pri < PRIO_MIN || pri > PRIO_MAX) + return EINVAL; + + if(which_proc < 0 || which_proc >= NR_TASKS+NR_PROCS) + return EINVAL; + + which_procp = proc_addr(which_proc); + + q = MAX_USER_Q + (pri - PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / (PRIO_MAX-PRIO_MIN+1); + + /* The below shouldn't happen. */ + if(q < MAX_USER_Q) q = MAX_USER_Q; + if(q > MIN_USER_Q) q = MIN_USER_Q; + + /* max_priority is the base priority. */ + which_procp->p_max_priority = q; + lock_unready(which_procp); + which_procp->p_priority = q; + + /* Runnable? Put it (back) on its new run queue. */ + if(!which_procp->p_rts_flags) + lock_ready(which_procp); + + return OK; +} + + diff --git a/lib/posix/Makefile b/lib/posix/Makefile index 4c6e39285..56b0f258a 100755 --- a/lib/posix/Makefile +++ b/lib/posix/Makefile @@ -98,6 +98,7 @@ OBJECTS = \ $(LIBRARY)(gettimeofday.o) \ $(LIBRARY)(getopt.o) \ $(LIBRARY)(lstat.o) \ + $(LIBRARY)(priority.o) \ $(LIBRARY)(readlink.o) \ $(LIBRARY)(symlink.o) \ @@ -375,6 +376,9 @@ $(LIBRARY)(gettimeofday.o): gettimeofday.c $(LIBRARY)(getopt.o): getopt.c $(CC1) getopt.c +$(LIBRARY)(priority.o): priority.c + $(CC1) priority.c + $(LIBRARY)(readlink.o): readlink.c $(CC1) readlink.c diff --git a/lib/posix/priority.c b/lib/posix/priority.c new file mode 100644 index 000000000..29c68c9b0 --- /dev/null +++ b/lib/posix/priority.c @@ -0,0 +1,46 @@ +/* +priority.c +*/ + +#include +#include +#include +#include +#include +#include +#include + + +int getpriority(int which, int who) +{ + int v; + message m; + + m.m1_i1 = which; + m.m1_i2 = who; + + /* GETPRIORITY returns negative for error. + * Otherwise, it returns the priority plus the minimum + * priority, to distiginuish from error. We have to + * correct for this. (The user program has to check errno + * to see if something really went wrong.) + */ + + if((v = _syscall(MM, GETPRIORITY, &m)) < 0) { + return v; + } + + return v + PRIO_MIN; +} + +int setpriority(int which, int who, int prio) +{ + message m; + + m.m1_i1 = which; + m.m1_i2 = who; + m.m1_i3 = prio; + + return _syscall(MM, SETPRIORITY, &m); +} + diff --git a/lib/syslib/Makefile b/lib/syslib/Makefile index 754cef428..d81869093 100755 --- a/lib/syslib/Makefile +++ b/lib/syslib/Makefile @@ -26,6 +26,7 @@ OBJECTS = \ $(LIBSYS)(sys_irqctl.o) \ $(LIBSYS)(sys_eniop.o) \ $(LIBSYS)(sys_segctl.o) \ + $(LIBSYS)(sys_setpriority.o) \ $(LIBSYS)(sys_umap.o) \ $(LIBSYS)(sys_physcp.o) \ $(LIBSYS)(sys_vircp.o) \ @@ -88,6 +89,9 @@ $(LIBSYS)(sys_irqctl.o): sys_irqctl.c $(LIBSYS)(sys_eniop.o): sys_eniop.c $(CC1) sys_eniop.c +$(LIBSYS)(sys_setpriority.o): sys_setpriority.c + $(CC1) sys_setpriority.c + $(LIBSYS)(sys_segctl.o): sys_segctl.c $(CC1) sys_segctl.c diff --git a/lib/syslib/sys_setpriority.c b/lib/syslib/sys_setpriority.c new file mode 100755 index 000000000..942d7c772 --- /dev/null +++ b/lib/syslib/sys_setpriority.c @@ -0,0 +1,13 @@ +#include "syslib.h" + +/*===========================================================================* + * sys_xit * + *===========================================================================*/ +PUBLIC int sys_setpriority(int proc, int prio) +{ + message m; + + m.m1_i1 = proc; + m.m1_i2 = prio; + return(_taskcall(SYSTASK, SYS_SETPRIORITY, &m)); +}