. use library function to parse memory string
[minix3.git] / kernel / profile.c
blob7e5d6aac8e385da253231aaf04ac807fa689153c
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 #if SPROFILE || CPROFILE
22 #include <minix/profile.h>
23 #include <minix/portio.h>
24 #include "kernel.h"
25 #include "profile.h"
26 #include "proc.h"
28 #endif
30 #if SPROFILE
32 #include <string.h>
34 /* Function prototype for the profiling clock handler. */
35 FORWARD _PROTOTYPE( int profile_clock_handler, (irq_hook_t *hook) );
37 /* A hook for the profiling clock interrupt handler. */
38 PRIVATE irq_hook_t profile_clock_hook;
40 /*===========================================================================*
41 * init_profile_clock *
42 *===========================================================================*/
43 PUBLIC void init_profile_clock(u32_t freq)
45 int r, irq;
47 intr_disable();
49 if((irq = arch_init_profile_clock(freq)) >= 0) {
50 /* Register interrupt handler for statistical system profiling. */
51 profile_clock_hook.proc_nr_e = CLOCK;
52 put_irq_handler(&profile_clock_hook, irq, profile_clock_handler);
53 enable_irq(&profile_clock_hook);
56 intr_enable();
59 /*===========================================================================*
60 * profile_clock_stop *
61 *===========================================================================*/
62 PUBLIC void stop_profile_clock()
64 intr_disable();
65 arch_stop_profile_clock();
66 intr_enable();
68 /* Unregister interrupt handler. */
69 disable_irq(&profile_clock_hook);
70 rm_irq_handler(&profile_clock_hook);
73 /*===========================================================================*
74 * profile_clock_handler *
75 *===========================================================================*/
76 PRIVATE int profile_clock_handler(hook)
77 irq_hook_t *hook;
79 /* This executes on every tick of the CMOS timer. */
81 /* Are we profiling, and profiling memory not full? */
82 if (!sprofiling || sprof_info.mem_used == -1) return (1);
84 /* Check if enough memory available before writing sample. */
85 if (sprof_info.mem_used + sizeof(sprof_info) > sprof_mem_size) {
86 sprof_info.mem_used = -1;
87 return(1);
90 /* All is OK */
92 /* Idle process? */
93 if (priv(proc_ptr)->s_proc_nr == IDLE) {
94 sprof_info.idle_samples++;
95 } else
96 /* Runnable system process? */
97 if (priv(proc_ptr)->s_flags & SYS_PROC && !proc_ptr->p_rts_flags) {
98 /* Note: k_reenter is always 0 here. */
100 /* Store sample (process name and program counter). */
101 phys_copy(vir2phys(proc_ptr->p_name),
102 (phys_bytes) (sprof_data_addr + sprof_info.mem_used),
103 (phys_bytes) strlen(proc_ptr->p_name));
105 phys_copy(vir2phys(&proc_ptr->p_reg.pc),
106 (phys_bytes) (sprof_data_addr+sprof_info.mem_used +
107 sizeof(proc_ptr->p_name)),
108 (phys_bytes) sizeof(proc_ptr->p_reg.pc));
110 sprof_info.mem_used += sizeof(sprof_sample);
112 sprof_info.system_samples++;
113 } else {
114 /* User process. */
115 sprof_info.user_samples++;
118 sprof_info.total_samples++;
120 /* Acknowledge interrupt if necessary. */
121 arch_ack_profile_clock();
123 return(1); /* reenable interrupts */
126 #endif /* SPROFILE */
129 #if CPROFILE
132 * The following variables and functions are used by the procentry/
133 * procentry syslib functions when linked with kernelspace processes.
134 * For userspace processes, the same variables and function are defined
135 * elsewhere. This enables different functionality and variable sizes,
136 * which is needed is a few cases.
139 /* A small table is declared for the kernelspace processes. */
140 struct cprof_tbl_s cprof_tbl[CPROF_TABLE_SIZE_KERNEL];
142 /* Function that returns table size. */
143 PUBLIC int profile_get_tbl_size(void)
145 return CPROF_TABLE_SIZE_KERNEL;
148 /* Function that returns on which execution of procentry to announce. */
149 PUBLIC int profile_get_announce(void)
151 return CPROF_ACCOUNCE_KERNEL;
155 * The kernel "announces" its control struct and table locations
156 * to itself through this function.
158 PUBLIC void profile_register(ctl_ptr, tbl_ptr)
159 void *ctl_ptr;
160 void *tbl_ptr;
162 int len, proc_nr;
163 vir_bytes vir_dst;
164 struct proc *rp;
166 /* Store process name, control struct, table locations. */
167 proc_nr = KERNEL;
168 rp = proc_addr(proc_nr);
170 cprof_proc_info[cprof_procs_no].endpt = rp->p_endpoint;
171 cprof_proc_info[cprof_procs_no].name = rp->p_name;
173 len = (phys_bytes) sizeof (void *);
175 vir_dst = (vir_bytes) ctl_ptr;
176 cprof_proc_info[cprof_procs_no].ctl =
177 numap_local(proc_nr, vir_dst, len);
179 vir_dst = (vir_bytes) tbl_ptr;
180 cprof_proc_info[cprof_procs_no].buf =
181 numap_local(proc_nr, vir_dst, len);
183 cprof_procs_no++;
186 #endif /* CPROFILE */