vm: include no-caching bits in PTF_ALLFLAGS for flags sanity check.
[minix.git] / kernel / profile.c
blob84ec551ba5ac8f95a753efe5f0b194ef6cc98834
1 /*
2 * This file contains several functions and variables used for system
3 * profiling.
5 * Statistical Profiling:
6 * The interrupt handler for profiling clock.
8 * Call Profiling:
9 * The table used for profiling data and a function to get its size.
11 * The function used by kernelspace processes to register the locations
12 * of their control struct and profiling table.
14 * Changes:
15 * 14 Aug, 2006 Created, (Rogier Meurs)
18 #include <minix/config.h>
20 #include <minix/profile.h>
21 #include <minix/portio.h>
22 #include "kernel.h"
23 #include "profile.h"
24 #include "proc.h"
26 #if SPROFILE
28 #include <string.h>
30 /* Function prototype for the profiling clock handler. */
31 FORWARD _PROTOTYPE( int profile_clock_handler, (irq_hook_t *hook) );
33 /* A hook for the profiling clock interrupt handler. */
34 PRIVATE irq_hook_t profile_clock_hook;
36 /*===========================================================================*
37 * init_profile_clock *
38 *===========================================================================*/
39 PUBLIC void init_profile_clock(u32_t freq)
41 int irq;
43 intr_disable();
45 if((irq = arch_init_profile_clock(freq)) >= 0) {
46 /* Register interrupt handler for statistical system profiling. */
47 profile_clock_hook.proc_nr_e = CLOCK;
48 put_irq_handler(&profile_clock_hook, irq, profile_clock_handler);
49 enable_irq(&profile_clock_hook);
52 intr_enable();
55 /*===========================================================================*
56 * profile_clock_stop *
57 *===========================================================================*/
58 PUBLIC void stop_profile_clock()
60 intr_disable();
61 arch_stop_profile_clock();
62 intr_enable();
64 /* Unregister interrupt handler. */
65 disable_irq(&profile_clock_hook);
66 rm_irq_handler(&profile_clock_hook);
69 /*===========================================================================*
70 * profile_clock_handler *
71 *===========================================================================*/
72 PRIVATE int profile_clock_handler(irq_hook_t *hook)
74 /* This executes on every tick of the CMOS timer. */
76 /* Are we profiling, and profiling memory not full? */
77 if (!sprofiling || sprof_info.mem_used == -1) return (1);
79 /* Check if enough memory available before writing sample. */
80 if (sprof_info.mem_used + sizeof(sprof_info) > sprof_mem_size) {
81 sprof_info.mem_used = -1;
82 return(1);
85 /* All is OK */
87 /* Idle process? */
88 if (priv(proc_ptr)->s_proc_nr == IDLE) {
89 sprof_info.idle_samples++;
90 } else
91 /* Runnable system process? */
92 if (priv(proc_ptr)->s_flags & SYS_PROC && proc_is_runnable(proc_ptr)) {
93 /* Note: k_reenter is always 0 here. */
95 /* Store sample (process name and program counter). */
96 data_copy(KERNEL, (vir_bytes) proc_ptr->p_name,
97 sprof_ep, sprof_data_addr_vir + sprof_info.mem_used,
98 strlen(proc_ptr->p_name));
100 data_copy(KERNEL, (vir_bytes) &proc_ptr->p_reg.pc, sprof_ep,
101 (vir_bytes) (sprof_data_addr_vir + sprof_info.mem_used +
102 sizeof(proc_ptr->p_name)),
103 (vir_bytes) sizeof(proc_ptr->p_reg.pc));
105 sprof_info.mem_used += sizeof(sprof_sample);
107 sprof_info.system_samples++;
108 } else {
109 /* User process. */
110 sprof_info.user_samples++;
113 sprof_info.total_samples++;
115 /* Acknowledge interrupt if necessary. */
116 arch_ack_profile_clock();
118 return(1); /* reenable interrupts */
121 #endif /* SPROFILE */
123 #if CPROFILE
125 * The following variables and functions are used by the procentry/
126 * procentry syslib functions when linked with kernelspace processes.
127 * For userspace processes, the same variables and function are defined
128 * elsewhere. This enables different functionality and variable sizes,
129 * which is needed is a few cases.
132 /* A small table is declared for the kernelspace processes. */
133 struct cprof_tbl_s cprof_tbl[CPROF_TABLE_SIZE_KERNEL];
135 /* Function that returns table size. */
136 PUBLIC int profile_get_tbl_size(void)
138 return CPROF_TABLE_SIZE_KERNEL;
141 /* Function that returns on which execution of procentry to announce. */
142 PUBLIC int profile_get_announce(void)
144 return CPROF_ACCOUNCE_KERNEL;
148 * The kernel "announces" its control struct and table locations
149 * to itself through this function.
151 PUBLIC void profile_register(ctl_ptr, tbl_ptr)
152 void *ctl_ptr;
153 void *tbl_ptr;
155 int proc_nr;
156 vir_bytes vir_dst;
157 struct proc *rp;
159 if(cprof_procs_no >= NR_SYS_PROCS)
160 return;
162 /* Store process name, control struct, table locations. */
163 rp = proc_addr(SYSTEM);
165 cprof_proc_info[cprof_procs_no].endpt = rp->p_endpoint;
166 cprof_proc_info[cprof_procs_no].name = rp->p_name;
167 cprof_proc_info[cprof_procs_no].ctl_v = (vir_bytes) ctl_ptr;
168 cprof_proc_info[cprof_procs_no].buf_v = (vir_bytes) tbl_ptr;
170 cprof_procs_no++;
173 #endif