]> Zhao Yanbai Git Server - minix.git/commitdiff
Added args to lock() and unlock() to tell them apart, for use
authorBen Gras <ben@minix3.org>
Wed, 1 Jun 2005 09:37:52 +0000 (09:37 +0000)
committerBen Gras <ben@minix3.org>
Wed, 1 Jun 2005 09:37:52 +0000 (09:37 +0000)
when lock timing is enabled in minix/config.h.

Added phys_zero() routine to klib386.s that zeroes a range of memory, and
added corresponding system call.

17 files changed:
kernel/clock.c
kernel/const.h
kernel/debug.h [new file with mode: 0644]
kernel/exception.c
kernel/glo.h
kernel/i8259.c
kernel/klib386.s
kernel/proc.c
kernel/proto.h
kernel/system.c
kernel/system.h
kernel/system/clock.c
kernel/system/copying.c
kernel/system/debugging.c
kernel/system/devio.c
kernel/system/misc.c
kernel/system/proctl.c

index 1a10c22406bdf7273ade96cbd42a7e0dc07acfdb..8ca80f5a95557a9112dd1866cdfbdf687c729495 100755 (executable)
@@ -33,6 +33,7 @@
  */
 
 #include "kernel.h"
+#include "debug.h"
 #include "proc.h"
 #include <signal.h>
 #include <minix/com.h>
@@ -107,10 +108,10 @@ PUBLIC void clock_task()
       receive(ANY, &m);        
 
       /* Transfer ticks seen by the low level handler. */
-      lock();
+      lock(8, "realtime");
       realtime += pending_ticks;       
       pending_ticks = 0;               
-      unlock();
+      unlock(8);
 
       /* Handle the request. */
       switch (m.m_type) {
@@ -267,9 +268,9 @@ PUBLIC clock_t get_uptime()
  */
   clock_t uptime;
 
-  lock();
+  lock(9, "get_uptime");
   uptime = realtime + pending_ticks;
-  unlock();
+  unlock(9);
   return(uptime);
 }
 
@@ -348,11 +349,11 @@ PUBLIC unsigned long read_clock()
  */
   unsigned count;
 
-  lock();
+  lock(10, "read_clock");
   outb(TIMER_MODE, LATCH_COUNT);
   count = inb(TIMER0);
   count |= (inb(TIMER0) << 8);
-  unlock();
+  unlock(10);
   
   return count;
 }
index ae89e4f14d14669a9d795aa28d844d16bfca40c6..6fdb7207d38938da87c22f501f23f6bdb4cac9a1 100755 (executable)
@@ -3,6 +3,7 @@
 #include <ibm/interrupt.h>     /* interrupt numbers and hardware vectors */
 #include <ibm/ports.h>         /* port addresses and magic numbers */
 #include <ibm/bios.h>          /* BIOS addresses, sizes and magic numbers */
+#include <minix/config.h>
 
 /* To translate an address in kernel space to a physical address.  This is
  * the same as umap_local(proc_ptr, D, vir, sizeof(*vir)), but less costly.
 #define IF_MASK 0x00000200
 #define IOPL_MASK 0x003000
 
+#if ENABLE_LOCK_TIMING
+#define locktimestart(c, v) timer_start(c, v)
+#define locktimeend(c) timer_end(c)
+#else
+#define locktimestart(c, v)
+#define locktimeend(c)
+#endif
+
 /* Disable/Enable hardware interrupts. */
-#define lock()         intr_disable()
-#define unlock()       intr_enable()
+#define lock(c, v)     do { intr_disable(); locktimestart(c, v); } while(0);
+#define unlock(c)      do { locktimeend(c); intr_enable();   } while(0);
 
 /* Sizes of memory tables. The boot monitor distinguishes three memory areas, 
  * namely low mem below 1M, 1M-16M, and mem after 16M. More chunks are needed
@@ -77,3 +86,7 @@
 /* M68000 specific constants go here. */
 #endif /* (CHIP == M68000) */
 
+#if ENABLE_INT_TIMING
+#define INT_TIMING_BITS                12
+#define INT_TIMING_ELEMENTS    (1L << 12)
+#endif
diff --git a/kernel/debug.h b/kernel/debug.h
new file mode 100644 (file)
index 0000000..3382330
--- /dev/null
@@ -0,0 +1,16 @@
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <minix/config.h>
+
+#if ENABLE_LOCK_TIMING
+_PROTOTYPE( void timer_start, (int cat, char *name) );
+_PROTOTYPE( void timer_end, (int cat) );
+#endif
+
+#if ENABLE_K_DEBUGGING                                         /* debugging */
+_PROTOTYPE( void check_runqueues, (char *when) );
+#endif
+
+#endif /* DEBUG_H */
index 6f97dca545db2a8c5196ccc80a541910c9ef663d..9e49fce951a95c7334e3b4bf627a3d8de8c530e8 100755 (executable)
@@ -9,6 +9,7 @@
 #include "kernel.h"
 #include <signal.h>
 #include "proc.h"
+#include "debug.h"
 
 /*==========================================================================*
  *                             exception                                   *
@@ -56,7 +57,7 @@ unsigned vec_nr;
   }
 
   if (k_reenter == 0 && ! istaskp(saved_proc)) {
-       unlock();               /* this is protected like sys_call() */
+       unlock(7);              /* this is protected like sys_call() */
        cause_sig(proc_nr(saved_proc), ep->signum);
        return;
   }
index dfa59d3137fbb1d69ff78a4eed0522661273a496..fe4154b7123558c63190f4fdcec08eba0daa47a6 100755 (executable)
@@ -7,6 +7,9 @@
 #define EXTERN
 #endif
 
+#include "const.h"
+#include <minix/config.h>
+
 /* MINIX' shutdown sequence uses watchdog timers to stop system services. The
  * flag shutting_down must be initialized to FALSE. We rely on the compiler's 
  * default initialization (0) of global variables here.
@@ -42,6 +45,11 @@ EXTERN irq_hook_t *irq_handlers[NR_IRQ_VECTORS];/* list of IRQ handlers */
 EXTERN int irq_actids[NR_IRQ_VECTORS];         /* IRQ ID bits active */
 EXTERN int irq_use;                    /* bit map of all in-use irq's */
 
+/* lock() timing data. */
+#if ENABLE_LOCK_TIMING
+EXTERN struct lock_timedata timingdata[TIMING_CATEGORIES];
+#endif
+
 /* Miscellaneous. */
 EXTERN reg_t mon_ss, mon_sp;   /* monitor stack */
 EXTERN int mon_return;         /* true if return to the monitor possible */
@@ -58,4 +66,3 @@ EXTERN _PROTOTYPE( void (*level0_func), (void) );
 /* M68000 specific variables go here. */
 #endif
 
-
index e2781b8f26d112e0c7763dc89c55ade154cf8233..7f60aaac5e896d6cbbe4335152851df8337735ca 100755 (executable)
@@ -7,6 +7,7 @@
 
 #include "kernel.h"
 #include "proc.h"
+#include "debug.h"
 #include <minix/com.h>
 
 #define ICW1_AT         0x11   /* edge triggered, cascade, need ICW4 */
@@ -48,7 +49,7 @@ int mine;
  */
   int i;
 
-  lock();
+  lock(6, "intr_init");
   if (machine.protected) {
        /* The AT and newer PS/2 have two interrupt controllers, one master,
         * one slaved at IRQ 2.  (We don't have to deal with the PC that
index 4bade860bd4c0e12c7b933137e77b5db2ad12a89..99efb682edebe8d95a417b4ee4b68dd82f83fef7 100755 (executable)
@@ -26,6 +26,7 @@
 .define        _enable_irq     ! enable an irq at the 8259 controller
 .define        _disable_irq    ! disable an irq
 .define        _phys_copy      ! copy data from anywhere to anywhere in memory
+.define        _phys_zero      ! zero data anywhere in memory
 .define        _mem_rdw        ! copy one word from [segment:offset]
 .define        _reset          ! reset the system
 .define        _idle_task      ! task executed when there is no work
@@ -437,6 +438,36 @@ pc_small:
        pop     esi
        ret
 
+!*===========================================================================*
+!*                             phys_zero                                    *
+!*===========================================================================*
+! PUBLIC void phys_zero(phys_bytes source, phys_bytes bytecount);
+! Zero a block of physical memory.
+
+       .align  16
+
+_phys_zero:
+       push    ebp
+       mov     ebp, esp
+       push    esi
+       push    ebx
+       push    ds
+       mov     esi, 8(ebp)
+       mov     eax, 12(ebp)
+       mov     ebx, FLAT_DS_SELECTOR
+       mov     ds, bx
+       shr     eax, 2
+zero_start:
+       mov     (esi), 0
+       add     esi, 4
+       dec     eax
+       jnz     zero_start
+zero_done:
+       pop     ds
+       pop     ebx
+       pop     esi
+       pop     ebp
+       ret
 
 !*===========================================================================*
 !*                             mem_rdw                                      *
@@ -501,7 +532,7 @@ _level0:
 !*===========================================================================*
 !*                           read_tsc                                       *
 !*===========================================================================*
-! PUBLIC void read_tsc(unsigned long *low, unsigned long *high);
+! PUBLIC void read_tsc(unsigned long *high, unsigned long *low);
 ! Read the cycle counter of the CPU. Pentium and up. 
 .align 16
 _read_tsc:
index d1a6cc6d788c036cf12e4cd1cbfd43ad4cb9aec5..a2be122e9415ec375843b2f2fc451040fd3aa57f 100755 (executable)
@@ -46,6 +46,7 @@
 #include <minix/callnr.h>
 #include <minix/com.h>
 #include "proc.h"
+#include "debug.h"
 #include "ipc.h"
 #include "sendmask.h"
 
@@ -440,11 +441,11 @@ message *m_ptr;                   /* pointer to message buffer */
   int result;
   struct proc *caller_ptr;
 
-  lock();
+  lock(0, "notify");
   kinfo.lock_notify ++;
   caller_ptr = (k_reenter >= 0) ? proc_addr(HARDWARE) : proc_ptr;
   result = mini_notify(caller_ptr, dst, m_ptr); 
-  unlock();
+  unlock(0);
   return(result);
 }
 
@@ -637,9 +638,9 @@ int queue;
 PUBLIC void lock_pick_proc()
 {
 /* Safe gateway to pick_proc() for tasks. */
-  lock();
+  lock(1, "pick_proc");
   pick_proc();
-  unlock();
+  unlock(1);
 }
 
 
@@ -652,10 +653,10 @@ message *m_ptr;                   /* pointer to message buffer */
 {
 /* Safe gateway to mini_send() for tasks. */
   int result;
-  lock();
+  lock(2, "send");
   kinfo.lock_send ++;
   result = mini_send(proc_ptr, dst, m_ptr, NON_BLOCKING);
-  unlock();
+  unlock(2);
   return(result);
 }
 
@@ -667,9 +668,9 @@ PUBLIC void lock_ready(rp)
 struct proc *rp;               /* this process is now runnable */
 {
 /* Safe gateway to ready() for tasks. */
-  lock();
+  lock(3, "ready");
   ready(rp);
-  unlock();
+  unlock(3);
 }
 
 /*==========================================================================*
@@ -679,9 +680,9 @@ PUBLIC void lock_unready(rp)
 struct proc *rp;               /* this process is no longer runnable */
 {
 /* Safe gateway to unready() for tasks. */
-  lock();
+  lock(4, "unready");
   unready(rp);
-  unlock();
+  unlock(4);
 }
 
 /*==========================================================================*
@@ -691,8 +692,8 @@ PUBLIC void lock_sched(queue)
 int queue;
 {
 /* Safe gateway to sched() for tasks. */
-  lock();
+  lock(5, "sched");
   sched(queue);
-  unlock();
+  unlock(5);
 }
 
index 4c04b3e88887148944d9ab83bc0786d31a87016e..33f600918e1e03e0f321b7766efa7b7e206db156 100755 (executable)
@@ -93,6 +93,7 @@ _PROTOTYPE( int disable_irq, (irq_hook_t *hook)                               );
 _PROTOTYPE( u16_t mem_rdw, (U16_t segm, vir_bytes offset)              );
 _PROTOTYPE( void phys_copy, (phys_bytes source, phys_bytes dest,
                phys_bytes count)                                       );
+_PROTOTYPE( void phys_zero, (phys_bytes source, phys_bytes count)      );
 _PROTOTYPE( void phys_insb, (U16_t port, phys_bytes buf, size_t count) );
 _PROTOTYPE( void phys_insw, (U16_t port, phys_bytes buf, size_t count) );
 _PROTOTYPE( void phys_outsb, (U16_t port, phys_bytes buf, size_t count));
@@ -100,7 +101,7 @@ _PROTOTYPE( void phys_outsw, (U16_t port, phys_bytes buf, size_t count));
 _PROTOTYPE( void reset, (void)                                         );
 _PROTOTYPE( void level0, (void (*func)(void))                          );
 _PROTOTYPE( void monitor, (void)                                       );
-_PROTOTYPE( void read_tsc, (unsigned long *low, unsigned long *high)   );
+_PROTOTYPE( void read_tsc, (unsigned long *high, unsigned long *low)   );
 
 /* mpx*.s */
 _PROTOTYPE( void idle_task, (void)                                     );
index a60bf4e0f94903a9eeccd130c2132429cece3e05..4a5e581f9595ea688fc3d720d3d747640cce4feb 100755 (executable)
@@ -162,6 +162,7 @@ PRIVATE void initialize(void)
   map(SYS_UMAP, do_umap);              /* map virtual to physical address */
   map(SYS_VIRCOPY, do_vircopy);        /* use pure virtual addressing */
   map(SYS_PHYSCOPY, do_physcopy);      /* use physical addressing */
+  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 */
 
index 403843f25e9f985eef9ca04a3dd184cf55059086..6f7ac9409eebb26bb9edc03a723655a163aa3fa9 100644 (file)
@@ -11,6 +11,7 @@
 
 /* Common includes for the system library. */
 #include <minix/com.h>
+#include <minix/config.h>
 #include "proc.h"
 #include "assert.h"
 
@@ -61,12 +62,9 @@ _PROTOTYPE( int do_trace, (message *m_ptr) );                /* process tracing */
 #define do_trace do_unused
 #endif
 
-#if ENABLE_K_DEBUGGING                                         /* debugging */
-_PROTOTYPE( void check_runqueues, (char *when) );
-#endif
-
 _PROTOTYPE( int do_vircopy, (message *m_ptr) );
 _PROTOTYPE( int do_physcopy, (message *m_ptr) );
+_PROTOTYPE( int do_physzero, (message *m_ptr) );
 _PROTOTYPE( int do_biosio, (message *m_ptr) );
 
 #endif /* SYSTEM_H */
index d096229ab516d2088575d773974f1f1d9cfccd5e..9a5223227a2ce3ad776453df40f61a9a98783124 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "../kernel.h"
 #include "../system.h"
+#include "../debug.h"
 #include <signal.h>
 
 /*===========================================================================*
@@ -27,11 +28,10 @@ register message *m_ptr;    /* pointer to request message */
   proc_nr = (m_ptr->T_PROC_NR == SELF) ? m_ptr->m_source : m_ptr->T_PROC_NR;
   if (isokprocn(proc_nr)) {
       rp = proc_addr(m_ptr->T_PROC_NR);
-
-      lock();                  /* halt the volatile time counters in rp */
+      lock(11, "do_times");                    /* halt the volatile time counters in rp */
       m_ptr->T_USER_TIME   = rp->p_user_time;
       m_ptr->T_SYSTEM_TIME = rp->p_sys_time;
-      unlock();
+      unlock(11);
   }
   m_ptr->T_BOOT_TICKS = get_uptime();  
   return(OK);
index 3778e4ce65a170ea47e775987d6fd51ec0eb75fa..566744bd2d30fe44fe912e786e24d635ad3e003a 100644 (file)
@@ -1,5 +1,5 @@
 /* The system call implemented in this file:
- *   m_type:   SYS_VIRCOPY, SYS_PHYSCOPY
+ *   m_type:   SYS_VIRCOPY, SYS_PHYSCOPY, SYS_PHYSZERO
  *
  * The parameters for this system call are:
  *    m5_c1:   CP_SRC_SPACE
@@ -114,6 +114,17 @@ register message *m_ptr;   /* pointer to request message */
   return(OK);
 }
 
+/*===========================================================================*
+ *                             do_physzero                                  *
+ *===========================================================================*/
+PUBLIC int do_physzero(m_ptr)
+register message *m_ptr;
+{
+/* Handle sys_physzero(). */
+  phys_zero((phys_bytes) m_ptr->PZ_MEM_PTR, (phys_bytes) m_ptr->PZ_COUNT);
+  return(OK);
+}
+
 
 /* The system call implemented in this file:
  *   m_type:   SYS_UMAP
index e683b42991dc049fd6639fc9f197f60f6e1db6ba..20b0f3f317b5bee8a149cf219d310250bb164a37 100644 (file)
@@ -7,6 +7,102 @@
 #include "../kernel.h"
 #include "../system.h"
 #include "../proc.h"
+#include "../glo.h"
+#include <limits.h>
+
+#if ENABLE_LOCK_TIMING
+
+static unsigned long starttimes[TIMING_CATEGORIES][2];
+
+#define HIGHCOUNT      0
+#define LOWCOUNT       1
+
+void timer_start(int cat, char *name)
+{
+       static int init = 0;
+       unsigned long h, l;
+       int i;
+
+       if(cat < 0 || cat >= TIMING_CATEGORIES) return;
+
+       for(i = 0; i < sizeof(timingdata[0].names) && *name; i++)
+               timingdata[cat].names[i] = *name++;
+       timingdata[0].names[sizeof(timingdata[0].names)-1] = '\0';
+
+       if(starttimes[cat][HIGHCOUNT]) {  return; }
+
+       if(!init) {
+               int t, f;
+               init = 1;
+               for(t = 0; t < TIMING_CATEGORIES; t++) {
+                       timingdata[t].lock_timings_range[0] = 0;
+                       timingdata[t].resets = timingdata[t].misses = 
+                               timingdata[t].measurements = 0;
+               }
+       }
+
+       read_tsc(&starttimes[cat][HIGHCOUNT], &starttimes[cat][LOWCOUNT]);
+
+       return;
+}
+
+void timer_end(int cat)
+{
+       unsigned long h, l, d = 0, binsize;
+       int bin;
+
+       read_tsc(&h, &l);
+       if(cat < 0 || cat >= TIMING_CATEGORIES) return;
+       if(!starttimes[cat][HIGHCOUNT]) {
+               timingdata[cat].misses++;
+               return;
+       }
+       if(starttimes[cat][HIGHCOUNT] == h) {
+               d = (l - starttimes[cat][1]);
+       } else if(starttimes[cat][HIGHCOUNT] == h-1 &&
+               starttimes[cat][LOWCOUNT] > l) {
+               d = ((ULONG_MAX - starttimes[cat][LOWCOUNT]) + l);
+       } else {
+               timingdata[cat].misses++;
+               return;
+       }
+       starttimes[cat][HIGHCOUNT] = 0;
+       if(!timingdata[cat].lock_timings_range[0] ||
+               d < timingdata[cat].lock_timings_range[0] ||
+               d > timingdata[cat].lock_timings_range[1]) {
+               int t;
+               if(!timingdata[cat].lock_timings_range[0] ||
+                       d < timingdata[cat].lock_timings_range[0])
+                       timingdata[cat].lock_timings_range[0] = d;
+               if(!timingdata[cat].lock_timings_range[1] ||
+                       d > timingdata[cat].lock_timings_range[1])
+                       timingdata[cat].lock_timings_range[1] = d;
+               for(t = 0; t < TIMING_POINTS; t++)
+                       timingdata[cat].lock_timings[t] = 0;
+               timingdata[cat].binsize =
+                       (timingdata[cat].lock_timings_range[1] -
+                       timingdata[cat].lock_timings_range[0])/(TIMING_POINTS+1);
+               if(timingdata[cat].binsize < 1)
+                 timingdata[cat].binsize = 1;
+               timingdata[cat].resets++;
+       }
+       bin = (d-timingdata[cat].lock_timings_range[0]) /
+               timingdata[cat].binsize;
+       if(bin < 0 || bin >= TIMING_POINTS) {
+               int t;
+               /* this indicates a bug, but isn't really serious */
+               for(t = 0; t < TIMING_POINTS; t++)
+                       timingdata[cat].lock_timings[t] = 0;
+               timingdata[cat].misses++;
+       } else {
+               timingdata[cat].lock_timings[bin]++;
+               timingdata[cat].measurements++;
+       }
+
+       return;
+}
+
+#endif
 
 #if ENABLE_K_DEBUGGING         /* only include code if enabled */
 
index 0f5feb21148b15d42ae39c5345395e9881ef396b..4991486955ea8a04d5baf2eb9f53b3e97eaf3cf1 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "../kernel.h"
 #include "../system.h"
+#include "../debug.h"
 #include <minix/devio.h>
 
 /*===========================================================================*
@@ -171,7 +172,7 @@ register message *m_ptr;    /* pointer to request message */
     * batch from being interrupted. It may be cleaner to do this just around 
     * the for loops, but this results in rather lenghty code.
     */
-    lock();
+    lock(13, "do_vdevio");
     switch (m_ptr->DIO_TYPE) {
         case DIO_BYTE:                                          /* byte values */
             pvb_pairs = (pvb_pair_t *) vdevio_pv_buf;
@@ -204,7 +205,7 @@ register message *m_ptr;    /* pointer to request message */
                     outl(pvb_pairs[i].port, pvl_pairs[i].value); 
             }
     }
-    unlock();    
+    unlock(13);
     
     /* Almost done, copy back results for input requests. */
     if (DIO_INPUT == m_ptr->REQUEST)
index c48a2bb38a88ab11b5e8021e2e14b68b5e426e4e..34f7946676a1cf0ff14b10bcadad0121ce13e33d 100644 (file)
@@ -1,6 +1,7 @@
 #include "../kernel.h"
 #include "../system.h"
 #include <unistd.h>
+#include <minix/config.h>
 INIT_ASSERT
 
 
@@ -187,6 +188,13 @@ register message *m_ptr;   /* pointer to request message */
         src_phys = vir2phys(&kmess);
         break;
     }
+#if ENABLE_LOCK_TIMING
+    case GET_LOCKTIMING: {
+       length = sizeof(timingdata);
+       src_phys = vir2phys(timingdata);
+       break;
+    }
+#endif
     default:
         return(EINVAL);
   }
index 32caf06eaa30b2ad8a80ccecd4c24f995680c933..42566983db008b8910dbd6d8049dc2db149efb05 100644 (file)
@@ -14,6 +14,7 @@
 #if (CHIP == INTEL)
 #include "../protect.h"
 #endif
+#include "../debug.h"
 
 INIT_ASSERT
 
@@ -200,6 +201,19 @@ message *m_ptr;                    /* pointer to request message */
   if (! isokprocn(exit_proc_nr)) return(EINVAL);
   rc = proc_addr(exit_proc_nr);
 
+#if DEAD_CODE
+  /* If this is a user process and the PM passed in a valid parent process, 
+   * accumulate the child times at the parent. 
+   */
+  if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
+      rp = proc_addr(m_ptr->PR_PPROC_NR);
+      lock(15, "do_xit");
+      rp->child_utime += rc->user_time + rc->child_utime;
+      rp->child_stime += rc->sys_time + rc->child_stime;
+      unlock(15);
+  }
+#endif
+
   /* Now call the routine to clean up of the process table slot. This cancels
    * outstanding timers, possibly removes the process from the message queues,
    * and resets important process table fields.