make vfs & filesystems use failable copying
[minix3.git] / kernel / system / do_sprofile.c
blobb992016afb77c0ba3de14f41130ab0510af1630d
1 /* The kernel call that is implemented in this file:
2 * m_type: SYS_SPROFILE
4 * The parameters for this kernel call are:
5 * m7_i1: PROF_ACTION (start/stop profiling)
6 * m7_i2: PROF_MEM_SIZE (available memory for data)
7 * m7_i3: PROF_FREQ (requested sample frequency)
8 * m7_i4: PROF_ENDPT (endpoint of caller)
9 * m7_p1: PROF_CTL_PTR (location of info struct)
10 * m7_p2: PROF_MEM_PTR (location of memory for data)
12 * Changes:
13 * 14 Aug, 2006 Created (Rogier Meurs)
16 #include "kernel/system.h"
17 #include "kernel/watchdog.h"
19 #if SPROFILE
21 /* user address to write info struct */
22 static vir_bytes sprof_info_addr_vir;
24 static void clean_seen_flag(void)
26 int i;
28 for (i = 0; i < NR_TASKS + NR_PROCS; i++)
29 proc[i].p_misc_flags &= ~MF_SPROF_SEEN;
32 /*===========================================================================*
33 * do_sprofile *
34 *===========================================================================*/
35 int do_sprofile(struct proc * caller, message * m_ptr)
37 int proc_nr;
38 int err;
40 switch(m_ptr->PROF_ACTION) {
42 case PROF_START:
43 /* Starting profiling.
45 * Check if profiling is not already running. Calculate physical
46 * addresses of user pointers. Reset counters. Start CMOS timer.
47 * Turn on profiling.
49 if (sprofiling) {
50 printf("SYSTEM: start s-profiling: already started\n");
51 return EBUSY;
54 /* Test endpoint number. */
55 if(!isokendpt(m_ptr->PROF_ENDPT, &proc_nr))
56 return EINVAL;
58 /* Set parameters for statistical profiler. */
59 sprof_ep = m_ptr->PROF_ENDPT;
60 sprof_info_addr_vir = (vir_bytes) m_ptr->PROF_CTL_PTR;
61 sprof_data_addr_vir = (vir_bytes) m_ptr->PROF_MEM_PTR;
63 sprof_info.mem_used = 0;
64 sprof_info.total_samples = 0;
65 sprof_info.idle_samples = 0;
66 sprof_info.system_samples = 0;
67 sprof_info.user_samples = 0;
69 sprof_mem_size = m_ptr->PROF_MEM_SIZE < SAMPLE_BUFFER_SIZE ?
70 m_ptr->PROF_MEM_SIZE : SAMPLE_BUFFER_SIZE;
72 switch (sprofiling_type = m_ptr->PROF_INTR_TYPE) {
73 case PROF_RTC:
74 init_profile_clock(m_ptr->PROF_FREQ);
75 break;
76 case PROF_NMI:
77 err = nmi_watchdog_start_profiling(m_ptr->PROF_FREQ);
78 if (err)
79 return err;
80 break;
81 default:
82 printf("ERROR : unknown profiling interrupt type\n");
83 return EINVAL;
86 sprofiling = 1;
88 clean_seen_flag();
90 return OK;
92 case PROF_STOP:
93 /* Stopping profiling.
95 * Check if profiling is indeed running. Turn off profiling.
96 * Stop CMOS timer. Copy info struct to user process.
98 if (!sprofiling) {
99 printf("SYSTEM: stop s-profiling: not started\n");
100 return EBUSY;
103 sprofiling = 0;
105 switch (sprofiling_type) {
106 case PROF_RTC:
107 stop_profile_clock();
108 break;
109 case PROF_NMI:
110 nmi_watchdog_stop_profiling();
111 break;
114 data_copy(KERNEL, (vir_bytes) &sprof_info,
115 sprof_ep, sprof_info_addr_vir, sizeof(sprof_info));
116 data_copy(KERNEL, (vir_bytes) sprof_sample_buffer,
117 sprof_ep, sprof_data_addr_vir, sprof_info.mem_used);
119 clean_seen_flag();
121 return OK;
123 default:
124 return EINVAL;
128 #endif /* SPROFILE */