Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / kernel / profile.c
blob61d1ee7660854c377d22d5aa91d89359af83d076
1 /*
2 * This file contains several functions and variables used for statistical
3 * system profiling, in particular the interrupt handler for profiling clock.
5 * Changes:
6 * 14 Aug, 2006 Created, (Rogier Meurs)
7 */
9 #include "kernel/kernel.h"
11 #if SPROFILE
13 #include <string.h>
14 #include "watchdog.h"
16 char sprof_sample_buffer[SAMPLE_BUFFER_SIZE];
18 /* Function prototype for the profiling clock handler. */
19 static int profile_clock_handler(irq_hook_t *hook);
21 /* A hook for the profiling clock interrupt handler. */
22 static irq_hook_t profile_clock_hook;
24 /*===========================================================================*
25 * init_profile_clock *
26 *===========================================================================*/
27 void init_profile_clock(u32_t freq)
29 int irq;
31 if((irq = arch_init_profile_clock(freq)) >= 0) {
32 /* Register interrupt handler for statistical system profiling. */
33 profile_clock_hook.proc_nr_e = CLOCK;
34 put_irq_handler(&profile_clock_hook, irq, profile_clock_handler);
35 enable_irq(&profile_clock_hook);
39 /*===========================================================================*
40 * profile_clock_stop *
41 *===========================================================================*/
42 void stop_profile_clock(void)
44 arch_stop_profile_clock();
46 /* Unregister interrupt handler. */
47 disable_irq(&profile_clock_hook);
48 rm_irq_handler(&profile_clock_hook);
51 static void sprof_save_sample(struct proc * p, void * pc)
53 struct sprof_sample *s;
55 s = (struct sprof_sample *) (sprof_sample_buffer + sprof_info.mem_used);
57 s->proc = p->p_endpoint;
58 s->pc = pc;
60 sprof_info.mem_used += sizeof(struct sprof_sample);
63 static void sprof_save_proc(struct proc * p)
65 struct sprof_proc * s;
67 s = (struct sprof_proc *) (sprof_sample_buffer + sprof_info.mem_used);
69 s->proc = p->p_endpoint;
70 strcpy(s->name, p->p_name);
72 sprof_info.mem_used += sizeof(struct sprof_proc);
75 static void profile_sample(struct proc * p, void * pc)
77 /* This executes on every tick of the CMOS timer. */
79 /* Are we profiling, and profiling memory not full? */
80 if (!sprofiling || sprof_info.mem_used == -1)
81 return;
83 /* Check if enough memory available before writing sample. */
84 if (sprof_info.mem_used + sizeof(sprof_info) +
85 2*sizeof(struct sprof_sample) +
86 2*sizeof(struct sprof_sample) > sprof_mem_size) {
87 sprof_info.mem_used = -1;
88 return;
91 /* Runnable system process? */
92 if (p->p_endpoint == IDLE)
93 sprof_info.idle_samples++;
94 else if (p->p_endpoint == KERNEL ||
95 (priv(p)->s_flags & SYS_PROC && proc_is_runnable(p))) {
97 if (!(p->p_misc_flags & MF_SPROF_SEEN)) {
98 p->p_misc_flags |= MF_SPROF_SEEN;
99 sprof_save_proc(p);
102 sprof_save_sample(p, pc);
103 sprof_info.system_samples++;
104 } else {
105 /* User process. */
106 sprof_info.user_samples++;
109 sprof_info.total_samples++;
112 /*===========================================================================*
113 * profile_clock_handler *
114 *===========================================================================*/
115 static int profile_clock_handler(irq_hook_t *hook)
117 struct proc * p;
118 p = get_cpulocal_var(proc_ptr);
120 profile_sample(p, (void *) p->p_reg.pc);
122 /* Acknowledge interrupt if necessary. */
123 arch_ack_profile_clock();
125 return(1); /* reenable interrupts */
128 void nmi_sprofile_handler(struct nmi_frame * frame)
130 struct proc * p = get_cpulocal_var(proc_ptr);
132 * test if the kernel was interrupted. If so, save first a sample fo
133 * kernel and than for the current process, otherwise save just the
134 * process
136 if (nmi_in_kernel(frame)) {
137 struct proc *kern;
140 * if we sample kernel, check if IDLE is scheduled. If so,
141 * account for idle time rather than taking kernel sample
143 if (p->p_endpoint == IDLE) {
144 sprof_info.idle_samples++;
145 sprof_info.total_samples++;
146 return;
149 kern = proc_addr(KERNEL);
151 profile_sample(kern, (void *) frame->pc);
153 else
154 profile_sample(p, (void *) frame->pc);
157 #endif /* SPROFILE */