Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / kernel / system / do_sprofile.c
blobd84e22c95f160a14aaa16715c692d36abdd75ecc
1 /* The kernel call that is implemented in this file:
2 * m_type: SYS_SPROF
4 * The parameters for this kernel call are:
5 * m_lsys_krn_sys_sprof.action (start/stop profiling)
6 * m_lsys_krn_sys_sprof.mem_size (available memory for data)
7 * m_lsys_krn_sys_sprof.freq (requested sample frequency)
8 * m_lsys_krn_sys_sprof.endpt (endpoint of caller)
9 * m_lsys_krn_sys_sprof.ctl_ptr (location of info struct)
10 * m_lsys_krn_sys_sprof.mem_ptr (location of memory for data)
11 * m_lsys_krn_sys_sprof.intr_type (interrupt source: RTC/NMI)
13 * Changes:
14 * 14 Aug, 2006 Created (Rogier Meurs)
17 #include "kernel/system.h"
18 #include "kernel/watchdog.h"
20 #if SPROFILE
22 /* user address to write info struct */
23 static vir_bytes sprof_info_addr_vir;
25 static void clean_seen_flag(void)
27 int i;
29 for (i = 0; i < NR_TASKS + NR_PROCS; i++)
30 proc[i].p_misc_flags &= ~MF_SPROF_SEEN;
33 /*===========================================================================*
34 * do_sprofile *
35 *===========================================================================*/
36 int do_sprofile(struct proc * caller, message * m_ptr)
38 int proc_nr;
39 int err;
41 switch(m_ptr->m_lsys_krn_sys_sprof.action) {
43 case PROF_START:
44 /* Starting profiling.
46 * Check if profiling is not already running. Calculate physical
47 * addresses of user pointers. Reset counters. Start CMOS timer.
48 * Turn on profiling.
50 if (sprofiling) {
51 printf("SYSTEM: start s-profiling: already started\n");
52 return EBUSY;
55 /* Test endpoint number. */
56 if(!isokendpt(m_ptr->m_lsys_krn_sys_sprof.endpt, &proc_nr))
57 return EINVAL;
59 /* Set parameters for statistical profiler. */
60 sprof_ep = m_ptr->m_lsys_krn_sys_sprof.endpt;
61 sprof_info_addr_vir = m_ptr->m_lsys_krn_sys_sprof.ctl_ptr;
62 sprof_data_addr_vir = m_ptr->m_lsys_krn_sys_sprof.mem_ptr;
64 sprof_info.mem_used = 0;
65 sprof_info.total_samples = 0;
66 sprof_info.idle_samples = 0;
67 sprof_info.system_samples = 0;
68 sprof_info.user_samples = 0;
70 sprof_mem_size =
71 m_ptr->m_lsys_krn_sys_sprof.mem_size < SAMPLE_BUFFER_SIZE ?
72 m_ptr->m_lsys_krn_sys_sprof.mem_size : SAMPLE_BUFFER_SIZE;
74 switch (sprofiling_type = m_ptr->m_lsys_krn_sys_sprof.intr_type) {
75 case PROF_RTC:
76 init_profile_clock(m_ptr->m_lsys_krn_sys_sprof.freq);
77 break;
78 case PROF_NMI:
79 err = nmi_watchdog_start_profiling(
80 m_ptr->m_lsys_krn_sys_sprof.freq);
81 if (err)
82 return err;
83 break;
84 default:
85 printf("ERROR : unknown profiling interrupt type\n");
86 return EINVAL;
89 sprofiling = 1;
91 clean_seen_flag();
93 return OK;
95 case PROF_STOP:
96 /* Stopping profiling.
98 * Check if profiling is indeed running. Turn off profiling.
99 * Stop CMOS timer. Copy info struct to user process.
101 if (!sprofiling) {
102 printf("SYSTEM: stop s-profiling: not started\n");
103 return EBUSY;
106 sprofiling = 0;
108 switch (sprofiling_type) {
109 case PROF_RTC:
110 stop_profile_clock();
111 break;
112 case PROF_NMI:
113 nmi_watchdog_stop_profiling();
114 break;
117 data_copy(KERNEL, (vir_bytes) &sprof_info,
118 sprof_ep, sprof_info_addr_vir, sizeof(sprof_info));
119 data_copy(KERNEL, (vir_bytes) sprof_sample_buffer,
120 sprof_ep, sprof_data_addr_vir, sprof_info.mem_used);
122 clean_seen_flag();
124 return OK;
126 default:
127 return EINVAL;
131 #endif /* SPROFILE */