Add 'getidle' CPU utilization measurement infrastructure
This commit is contained in:
@@ -8,7 +8,6 @@
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <minix/sysutil.h>
|
||||
#include "../../proc.h"
|
||||
#include "../../proto.h"
|
||||
#include "../../vm.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <minix/type.h>
|
||||
#include <minix/syslib.h>
|
||||
#include <minix/sysutil.h>
|
||||
#include <minix/cpufeature.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
@@ -119,7 +119,6 @@ struct tss_s {
|
||||
|
||||
EXTERN struct tss_s tss;
|
||||
|
||||
_PROTOTYPE( void prot_init, (void) );
|
||||
_PROTOTYPE( void idt_init, (void) );
|
||||
_PROTOTYPE( void init_codeseg, (struct segdesc_s *segdp, phys_bytes base,
|
||||
vir_bytes size, int privilege) );
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <ibm/bios.h>
|
||||
#include <minix/portio.h>
|
||||
#include <minix/u64.h>
|
||||
#include <minix/sysutil.h>
|
||||
#include <a.out.h>
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
@@ -118,6 +118,8 @@ PUBLIC int bsp_timer_int_handler(void)
|
||||
{
|
||||
unsigned ticks;
|
||||
|
||||
IDLE_STOP;
|
||||
|
||||
if(minix_panicing)
|
||||
return 0;
|
||||
|
||||
@@ -228,6 +230,8 @@ PUBLIC int ap_timer_int_handler(void)
|
||||
int expired = 0;
|
||||
struct proc * p, * billp;
|
||||
|
||||
IDLE_STOP;
|
||||
|
||||
/* Update user and system accounting times. Charge the current process
|
||||
* for user time. If the current process is not billable, that is, if a
|
||||
* non-user process is running, charge the billable process for system
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
#define lock reallock
|
||||
#define unlock realunlock
|
||||
|
||||
#ifdef CONFIG_IDLE_TSC
|
||||
#define IDLE_STOP if(idle_active) { read_tsc_64(&idle_stop); idle_active = 0; }
|
||||
#else
|
||||
#define IDLE_STOP
|
||||
#endif
|
||||
|
||||
/* args to intr_init() */
|
||||
#define INTS_ORIG 0 /* restore interrupts */
|
||||
#define INTS_MINIX 1 /* initialize interrupts for minix */
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef GLO_H
|
||||
#define GLO_H
|
||||
|
||||
#include <minix/sysutil.h>
|
||||
|
||||
/* Global variables used in the kernel. This file contains the declarations;
|
||||
* storage space for the variables is allocated in table.c, because EXTERN is
|
||||
* defined as extern unless the _TABLE definition is seen. We rely on the
|
||||
@@ -66,6 +64,12 @@ EXTERN int verboseflags;
|
||||
EXTERN int config_no_apic; /* optionaly turn off apic */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDLE_TSC
|
||||
EXTERN u64_t idle_tsc;
|
||||
EXTERN u64_t idle_stop;
|
||||
EXTERN int idle_active;
|
||||
#endif
|
||||
|
||||
/* VM */
|
||||
EXTERN int vm_running;
|
||||
EXTERN int catch_pagefaults;
|
||||
|
||||
@@ -112,6 +112,8 @@ PUBLIC void irq_handle(int irq)
|
||||
{
|
||||
irq_hook_t * hook;
|
||||
|
||||
IDLE_STOP;
|
||||
|
||||
/* here we need not to get this IRQ until all the handlers had a say */
|
||||
hw_intr_mask(irq);
|
||||
hook = irq_handlers[irq];
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#define CONFIG_APIC
|
||||
/* boot verbose */
|
||||
#define CONFIG_BOOT_VERBOSE
|
||||
/* measure cumulative idle timestamp counter ticks */
|
||||
#undef CONFIG_IDLE_TSC
|
||||
|
||||
/* This is the master header for the kernel. It includes some other files
|
||||
* and defines the principal constants.
|
||||
@@ -20,6 +22,7 @@
|
||||
#include <minix/const.h> /* MINIX specific constants */
|
||||
#include <minix/type.h> /* MINIX specific types, e.g. message */
|
||||
#include <minix/ipc.h> /* MINIX run-time system */
|
||||
#include <minix/sysutil.h> /* MINIX utility library functions */
|
||||
#include <timers.h> /* watchdog timer management */
|
||||
#include <errno.h> /* return codes and error numbers */
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/u64.h>
|
||||
#include "proc.h"
|
||||
#include "debug.h"
|
||||
#include "clock.h"
|
||||
@@ -189,6 +190,10 @@ PUBLIC void main()
|
||||
#endif /* SPROFILE */
|
||||
cprof_procs_no = 0; /* init nr of hash table slots used */
|
||||
|
||||
#ifdef CONFIG_IDLE_TSC
|
||||
idle_tsc = cvu64(0);
|
||||
#endif
|
||||
|
||||
vm_running = 0;
|
||||
krandom.random_sources = RANDOM_SOURCES;
|
||||
krandom.random_elements = RANDOM_ELEMENTS;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <signal.h>
|
||||
#include <minix/portio.h>
|
||||
#include <minix/u64.h>
|
||||
#include <minix/syslib.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "kernel.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
* other parts of the kernel through lock_...(). The lock temporarily disables
|
||||
* interrupts to prevent race conditions.
|
||||
*/
|
||||
FORWARD _PROTOTYPE( void idle, (void));
|
||||
FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst_e,
|
||||
message *m_ptr, int flags));
|
||||
FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src,
|
||||
@@ -123,6 +125,35 @@ PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
|
||||
NOREC_RETURN(queuemess, OK);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* idle *
|
||||
*===========================================================================*/
|
||||
PRIVATE void idle()
|
||||
{
|
||||
/* This function is called whenever there is no work to do.
|
||||
* Halt the CPU, and measure how many timestamp counter ticks are
|
||||
* spent not doing anything. This allows test setups to measure
|
||||
* the CPU utiliziation of certain workloads with high precision.
|
||||
*/
|
||||
#ifdef CONFIG_IDLE_TSC
|
||||
u64_t idle_start;
|
||||
|
||||
read_tsc_64(&idle_start);
|
||||
idle_active = 1;
|
||||
#endif
|
||||
|
||||
halt_cpu();
|
||||
|
||||
#ifdef CONFIG_IDLE_TSC
|
||||
if (idle_active) {
|
||||
IDLE_STOP;
|
||||
printf("Kernel: idle active after resuming CPU\n");
|
||||
}
|
||||
|
||||
idle_tsc = add64(idle_tsc, sub64(idle_stop, idle_start));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* schedcheck *
|
||||
*===========================================================================*/
|
||||
@@ -166,7 +197,7 @@ not_runnable_pick_new:
|
||||
proc_ptr = proc_addr(IDLE);
|
||||
if (priv(proc_ptr)->s_flags & BILLABLE)
|
||||
bill_ptr = proc_ptr;
|
||||
halt_cpu();
|
||||
idle();
|
||||
}
|
||||
|
||||
check_misc_flags:
|
||||
|
||||
@@ -19,6 +19,7 @@ _PROTOTYPE( void reset_timer, (struct timer *tp) );
|
||||
_PROTOTYPE( void ser_dump_proc, (void) );
|
||||
|
||||
/* main.c */
|
||||
_PROTOTYPE( void main, (void) );
|
||||
_PROTOTYPE( void prepare_shutdown, (int how) );
|
||||
_PROTOTYPE( void minix_shutdown, (struct timer *tp) );
|
||||
|
||||
@@ -102,6 +103,7 @@ _PROTOTYPE( void stop_profile_clock, (void) );
|
||||
#endif
|
||||
|
||||
/* functions defined in architecture-dependent files. */
|
||||
_PROTOTYPE( void prot_init, (void) );
|
||||
_PROTOTYPE( phys_bytes phys_copy, (phys_bytes source, phys_bytes dest,
|
||||
phys_bytes count) );
|
||||
_PROTOTYPE( void phys_copy_fault, (void));
|
||||
|
||||
@@ -141,18 +141,26 @@ register message *m_ptr; /* pointer to request message */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case GET_IRQACTIDS: {
|
||||
length = sizeof(irq_actids);
|
||||
src_vir = (vir_bytes) irq_actids;
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_PRIVID:
|
||||
case GET_PRIVID: {
|
||||
if (!isokendpt(m_ptr->I_VAL_LEN2_E, &proc_nr))
|
||||
return EINVAL;
|
||||
return proc_addr(proc_nr)->p_priv->s_id;
|
||||
|
||||
}
|
||||
case GET_IDLETSC: {
|
||||
#ifdef CONFIG_IDLE_TSC
|
||||
length = sizeof(idle_tsc);
|
||||
src_vir = (vir_bytes) &idle_tsc;
|
||||
break;
|
||||
#else
|
||||
kprintf("do_getinfo: kernel not compiled with CONFIG_IDLE_TSC\n");
|
||||
return(EINVAL);
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
kprintf("do_getinfo: invalid request %d\n", m_ptr->I_REQUEST);
|
||||
return(EINVAL);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <minix/sysutil.h>
|
||||
#include <minix/sys_config.h>
|
||||
|
||||
/*===========================================================================*
|
||||
|
||||
Reference in New Issue
Block a user