核心代码
mychange.txt
diff --git a/include/unistd.h b/include/unistd.h
index 9d13199..d715dda 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -143,7 +143,7 @@ int tcsetpgrp(int, pid_t);
__aconst char *ttyname(int);
int unlink(const char *);
ssize_t write(int, const void *, size_t);
-
+int chrt(long deadline);
/*
* IEEE Std 1003.2-92, adopted in X/Open Portability Guide Issue 4 and later
diff --git a/minix/commands/service/parse.c b/minix/commands/service/parse.c
index 478d2fa..100b4b4 100644
--- a/minix/commands/service/parse.c
+++ b/minix/commands/service/parse.c
@@ -846,6 +846,7 @@ struct
{ "VMCTL", SYS_VMCTL },
{ "MEMSET", SYS_MEMSET },
{ "PADCONF", SYS_PADCONF },
+ { "CHRT", SYS_CHRT},
{ NULL, 0 }
};
diff --git a/minix/include/minix/callnr.h b/minix/include/minix/callnr.h
index 6030687..d1aff0c 100644
--- a/minix/include/minix/callnr.h
+++ b/minix/include/minix/callnr.h
@@ -58,8 +58,8 @@
#define PM_GETEPINFO (PM_BASE + 45)
#define PM_GETPROCNR (PM_BASE + 46)
#define PM_GETSYSINFO (PM_BASE + 47)
-
-#define NR_PM_CALLS 48 /* highest number from base plus one */
+#define PM_CHRT (PM_BASE + 48)
+#define NR_PM_CALLS 49 /* highest number from base plus one */
/*===========================================================================*
* Calls to VFS *
diff --git a/minix/include/minix/com.h b/minix/include/minix/com.h
index 637f77c..d1a1a50 100644
--- a/minix/include/minix/com.h
+++ b/minix/include/minix/com.h
@@ -262,9 +262,9 @@
# define SYS_SAFEMEMSET (KERNEL_CALL + 56) /* sys_safememset() */
# define SYS_PADCONF (KERNEL_CALL + 57) /* sys_padconf() */
-
+# define SYS_CHRT (KERNEL_CALL + 58)
/* Total */
-#define NR_SYS_CALLS 58 /* number of kernel calls */
+#define NR_SYS_CALLS 59 /* number of kernel calls */
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
diff --git a/minix/include/minix/syslib.h b/minix/include/minix/syslib.h
index a9ac487..646e4d9 100644
--- a/minix/include/minix/syslib.h
+++ b/minix/include/minix/syslib.h
@@ -23,7 +23,8 @@ struct rusage;
/*==========================================================================*
* Minix system library. *
- *==========================================================================*/
+ *==========================================================================*/
+int sys_chrt(endpoint_t who,long deadline);
int _taskcall(endpoint_t who, int syscallnr, message *msgptr);
int _kernel_call(int syscallnr, message *msgptr);
diff --git a/minix/kernel/config.h b/minix/kernel/config.h
index a99b299..ca9b31a 100644
--- a/minix/kernel/config.h
+++ b/minix/kernel/config.h
@@ -45,6 +45,7 @@
#define USE_RUNCTL 1 /* control stop flags of a process */
#define USE_STATECTL 1 /* let a process control its state */
#define USE_MCONTEXT 1 /* enable getting/setting of machine context */
+#define USE_CHRT 1
#if defined(__arm__)
#define USE_PADCONF 1 /* configure pinmux */
diff --git a/minix/kernel/proc.c b/minix/kernel/proc.c
index 3dff67c..aba1d9f 100644
--- a/minix/kernel/proc.c
+++ b/minix/kernel/proc.c
@@ -1535,6 +1535,7 @@ void enqueue(
* This function can be used x-cpu as it always uses the queues of the cpu the
* process is assigned to.
*/
+ if (rp->p_deadline > 0)rp->p_priority = 5;
int q = rp->p_priority; /* scheduling queue to use */
struct proc **rdy_head, **rdy_tail;
@@ -1600,7 +1601,8 @@ void enqueue(
*/
static void enqueue_head(struct proc *rp)
{
- const int q = rp->p_priority; /* scheduling queue to use */
+ if (rp->p_deadline > 0)rp->p_priority = 5;
+ const int q = rp->p_priority; /* scheduling queue to use */
struct proc **rdy_head, **rdy_tail;
@@ -1733,6 +1735,16 @@ static struct proc * pick_proc(void)
TRACE(VF_PICKPROC, printf("cpu %d queue %d empty\n", cpuid, q););
continue;
}
+ if(q==5){
+ rp=rdy_head[q];
+ struct proc *cur = rp->p_nextready;
+ while(cur!=NULL) {
+ if(proc_is_runnable(cur) && (cur->p_deadline > 0)) {
+ if (rp->p_deadline > cur->p_deadline)rp = cur;
+ else if (rp->p_deadline == 0)rp = cur;
+ }
+ cur = cur->p_nextready;
+ }
assert(proc_is_runnable(rp));
if (priv(rp)->s_flags & BILLABLE)
get_cpulocal_var(bill_ptr) = rp; /* bill for system time */
diff --git a/minix/kernel/proc.h b/minix/kernel/proc.h
index f311535..71e2b8e 100644
--- a/minix/kernel/proc.h
+++ b/minix/kernel/proc.h
@@ -53,7 +53,7 @@ struct proc {
unsigned long ipc_async;
unsigned long preempted;
} p_accounting;
-
+ long p_deadline;
clock_t p_user_time; /* user time in ticks */
clock_t p_sys_time; /* sys time in ticks */
diff --git a/minix/kernel/system.c b/minix/kernel/system.c
index 2d1aee1..1cc8019 100644
--- a/minix/kernel/system.c
+++ b/minix/kernel/system.c
@@ -190,6 +190,7 @@ void system_init(void)
}
/* Process management. */
+ map(SYS_CHRT, do_chrt);
map(SYS_FORK, do_fork); /* a process forked a new process */
map(SYS_EXEC, do_exec); /* update process after execute */
map(SYS_CLEAR, do_clear); /* clean up after process exit */
diff --git a/minix/kernel/system.h b/minix/kernel/system.h
index d7bd99b..d2ba581 100644
--- a/minix/kernel/system.h
+++ b/minix/kernel/system.h
@@ -36,6 +36,10 @@ int do_exec(struct proc * caller, message *m_ptr);
#if ! USE_EXEC
#define do_exec NULL
#endif
+int do_chrt(struct proc * caller, message *m_ptr);
+#if ! USE_CHRT
+#define do_chrt NULL
+#endif
int do_fork(struct proc * caller, message *m_ptr);
#if ! USE_FORK
diff --git a/minix/kernel/system/Makefile.inc b/minix/kernel/system/Makefile.inc
index ef8cf2e..7ab4ad6 100644
--- a/minix/kernel/system/Makefile.inc
+++ b/minix/kernel/system/Makefile.inc
@@ -39,6 +39,7 @@ SRCS+= \
do_mcontext.c \
do_schedule.c \
do_schedctl.c \
+ do_chrt.c \
do_statectl.c
.if ${MACHINE_ARCH} == "i386"
diff --git a/minix/lib/libc/sys/Makefile.inc b/minix/lib/libc/sys/Makefile.inc
index 38fa560..8d0c665 100644
--- a/minix/lib/libc/sys/Makefile.inc
+++ b/minix/lib/libc/sys/Makefile.inc
@@ -22,7 +22,7 @@ SRCS+= accept.c access.c adjtime.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
sync.c syscall.c sysuname.c truncate.c umask.c unlink.c write.c \
utimensat.c utimes.c futimes.c lutimes.c futimens.c \
_exit.c _ucontext.c environ.c __getcwd.c vfork.c sizeup.c init.c \
- getrusage.c setrlimit.c setpgid.c
+ getrusage.c setrlimit.c setpgid.c chrt.c
# Minix specific syscalls / utils.
SRCS+= cprofile.c sprofile.c stack_utils.c _mcontext.c
diff --git a/minix/lib/libsys/Makefile b/minix/lib/libsys/Makefile
index e926f69..c3a41d4 100644
--- a/minix/lib/libsys/Makefile
+++ b/minix/lib/libsys/Makefile
@@ -56,6 +56,7 @@ SRCS+= \
sys_endsig.c \
sys_exec.c \
sys_exit.c \
+ sys_chrt.c \
sys_fork.c \
sys_getinfo.c \
sys_getsig.c \
diff --git a/minix/servers/pm/Makefile b/minix/servers/pm/Makefile
index 75f4c54..165e0a1 100644
--- a/minix/servers/pm/Makefile
+++ b/minix/servers/pm/Makefile
@@ -4,7 +4,7 @@
PROG= pm
SRCS= main.c forkexit.c exec.c time.c alarm.c \
signal.c utility.c table.c trace.c getset.c misc.c \
- profile.c mcontext.c schedule.c
+ profile.c mcontext.c schedule.c chrt.c
DPADD+= ${LIBSYS} ${LIBTIMERS}
LDADD+= -lsys -ltimers
diff --git a/minix/servers/pm/proto.h b/minix/servers/pm/proto.h
index 0d27fc8..c2e01bf 100644
--- a/minix/servers/pm/proto.h
+++ b/minix/servers/pm/proto.h
@@ -3,6 +3,8 @@
struct mproc;
#include <minix/timers.h>
+/* chrt.c */
+int do_chrt(void);
/* alarm.c */
int do_itimer(void);
diff --git a/minix/servers/pm/table.c b/minix/servers/pm/table.c
index 8c8e24a..5c05b0e 100644
--- a/minix/servers/pm/table.c
+++ b/minix/servers/pm/table.c
@@ -58,5 +58,6 @@ int (* const call_vec[NR_PM_CALLS])(void) = {
CALL(PM_EXEC_RESTART) = do_execrestart,
CALL(PM_GETEPINFO) = do_getepinfo, /* getepinfo(2) */
CALL(PM_GETPROCNR) = do_getprocnr, /* getprocnr(2) */
- CALL(PM_GETSYSINFO) = do_getsysinfo /* getsysinfo(2) */
+ CALL(PM_GETSYSINFO) = do_getsysinfo, /* getsysinfo(2) */
+ CALL(PM_CHRT) = do_chrt
};
test_code.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <lib.h>
#include <time.h>
void proc(int id);
int main(void)
{
//创建三个子进程,并赋予子进程id
for (int i = 1; i < 4; i++)
{
if (fork() == 0)
{
proc(i);
}
}
for (int i = 1; i < 4; i++)
waitpid(-1, NULL, 0);
return 0;
}
void proc(int id)
{
int loop;
switch (id)
{
case 1: //子进程1,设置deadline=25
chrt(25);
printf("proc1 set success\n");
sleep(1);
break;
case 2: //子进程2,设置deadline=15
chrt(15);
printf("proc2 set success\n");
sleep(1);
break;
case 3: //子进程3,普通进程
chrt(0);
printf("proc3 set success\n");
break;
}
for (loop = 1; loop < 40; loop++)
{
//子进程1在5s后设置deadline=5
if (id == 1 && loop == 5)
{
chrt(5);
printf("Change proc1 deadline to 5s\n");
}
//子进程3在10s后设置deadline=3
if (id == 3 && loop == 10)
{
chrt(3);
printf("Change proc3 deadline to 3s\n");
}
sleep(1); //睡眠,否则会打印很多信息
printf("prc%d heart beat %d\n", id, loop);
}
exit(0);
}
chrt.c
#include <sys/cdefs.h>
#include "namespace.h"
#include <lib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
int chrt(long deadline) {
message m;
struct timespec now;
memset(&m, 0, sizeof(m));
if (deadline<=0)return 0;
alarm((unsigned int)deadline);
clock_gettime(CLOCK_REALTIME, &now);
deadline+=now.tv_sec;
m.m2_l1=deadline;
return _syscall(PM_PROC_NR, PM_CHRT, &m);
}
do_chrt.c
#include "kernel/system.h"
#include "kernel/vm.h"
#include <signal.h>
#include <string.h>
#include <assert.h>
#include <minix/endpoint.h>
#include <minix/u64.h>
#if USE_CHRT
/*===========================================================================*
* do_chrt *
*===========================================================================*/
int do_chrt(struct proc* caller, message* m_ptr) {
struct proc* p;
p=proc_addr(m_ptr->m2_i1);
p->deadline=m_ptr->m2_l1;
return OK;
}
#endif /* USE_CHRT */
sys_chrt.c
#include "syslib.h"
int sys_chrt(endpoint_t proc_ep, long deadline){
message newm;
newm.m2_i1=proc_ep;
newm.m2_l1=deadline;
return _kernel_call(SYS_CHRT,&newm);
}