2 * This file contains several functions and variables used for system
5 * Statistical Profiling:
6 * The interrupt handler for profiling clock.
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.
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>
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
)
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
);
59 /*===========================================================================*
60 * profile_clock_stop *
61 *===========================================================================*/
62 PUBLIC
void stop_profile_clock()
65 arch_stop_profile_clock();
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
)
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;
93 if (priv(proc_ptr
)->s_proc_nr
== IDLE
) {
94 sprof_info
.idle_samples
++;
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
++;
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 */
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
)
166 /* Store process name, control struct, table locations. */
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
);
186 #endif /* CPROFILE */