* Fixed bug relating to nested locking in interrupt handlers. The nested lock

caused interrupts to be reenabled (due to unlock), which caused a race. The
problems were especially visible on slower machines.
* Relocated free memory parsing to process manager. This saved quite some
code at the kernel level. Text size was reduced by about 650 bytes.
* Removed locks for updating the realtime in the clock's main loop and the
get_uptime function. Interrupts are no longer reentrant, so realtime is
immediately updated.
This commit is contained in:
Jorrit Herder
2005-06-17 09:09:54 +00:00
parent 90b80ad31e
commit e0a98a4d65
13 changed files with 76 additions and 206 deletions
+24 -1
View File
@@ -1,3 +1,4 @@
#define NEW_TIME_COUNT 1
/* The file contais the clock task, which handles all time related functions.
* Important events that are handled by the CLOCK include alarm timers and
* (re)scheduling user processes.
@@ -84,7 +85,9 @@ PRIVATE clock_t realtime; /* real time clock */
/* Variables for and changed by the CLOCK's interrupt handler. */
PRIVATE irq_hook_t clock_hook;
#if ! NEW_TIME_COUNT
PRIVATE clock_t pending_ticks; /* ticks seen by low level only */
#endif
PRIVATE int sched_ticks = SCHED_RATE; /* counter: when 0, call scheduler */
PRIVATE struct proc *prev_ptr; /* last user process run by clock */
@@ -107,11 +110,13 @@ PUBLIC void clock_task()
/* Go get a message. */
receive(ANY, &m);
#if ! NEW_TIME_COUNT
/* Transfer ticks seen by the low level handler. */
lock(8, "realtime");
realtime += pending_ticks;
pending_ticks = 0;
unlock(8);
#endif
/* Handle the request. */
switch (m.m_type) {
@@ -202,10 +207,12 @@ irq_hook_t *hook;
* The variables which are changed require more care:
* rp->p_user_time, rp->p_sys_time:
* These are protected by explicit locks in system.c.
#if ! NEW_TIME_COUNT
* pending_ticks:
* This is protected by explicit locks in clock.c. Don't
* update realtime directly, since there are too many
* references to it to guard conveniently.
#endif
* lost_ticks:
* Clock ticks counted outside the clock task.
* sched_ticks, prev_ptr:
@@ -222,7 +229,9 @@ irq_hook_t *hook;
register struct proc *rp;
register unsigned ticks;
message m;
#if ! NEW_TIME_COUNT
clock_t now;
#endif
/* Acknowledge the PS/2 clock interrupt. */
if (machine.ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT);
@@ -232,10 +241,16 @@ irq_hook_t *hook;
* process is running, charge the billable process for system time as well.
* Thus the unbillable process' user time is the billable user's system time.
*/
#if NEW_TIME_COUNT
ticks = lost_ticks + 1;
lost_ticks = 0;
realtime += ticks;
#else
ticks = lost_ticks + 1;
lost_ticks = 0;
pending_ticks += ticks;
now = realtime + pending_ticks;
#endif
/* Update administration. */
proc_ptr->p_user_time += ticks;
@@ -244,11 +259,15 @@ irq_hook_t *hook;
/* Check if do_clocktick() must be called. Done for alarms and scheduling.
* If bill_ptr == prev_ptr, there are no ready users so don't need sched().
*/
#if NEW_TIME_COUNT
if (next_timeout <= realtime || (sched_ticks == 1 && bill_ptr == prev_ptr
#else
if (next_timeout <= now || (sched_ticks == 1 && bill_ptr == prev_ptr
#endif
&& rdy_head[PPRI_USER] != NIL_PROC))
{
m.NOTIFY_TYPE = HARD_INT;
lock_notify(CLOCK, &m);
int_notify(CLOCK, &m);
}
else if (--sched_ticks <= 0) {
sched_ticks = SCHED_RATE; /* reset the quantum */
@@ -266,12 +285,16 @@ PUBLIC clock_t get_uptime()
/* Get and return the current clock uptime in ticks.
* Be careful about pending_ticks.
*/
#if NEW_TIME_COUNT
return(realtime);
#else
clock_t uptime;
lock(9, "get_uptime");
uptime = realtime + pending_ticks;
unlock(9);
return(uptime);
#endif
}