panic() cleanup.
[minix.git] / kernel / system / do_cprofile.c
blob5b2c2661dd090a89f6cc480c087bf4ed744d4849
1 /* The kernel call that is implemented in this file:
2 * m_type: SYS_CPROFILE
4 * The parameters for this kernel call are:
5 * m7_i1: PROF_ACTION (get/reset profiling data)
6 * m7_i2: PROF_MEM_SIZE (available memory for data)
7 * m7_i4: PROF_ENDPT (endpoint of caller)
8 * m7_p1: PROF_CTL_PTR (location of info struct)
9 * m7_p2: PROF_MEM_PTR (location of memory for data)
11 * Changes:
12 * 14 Aug, 2006 Created (Rogier Meurs)
15 #include "../system.h"
17 #include <string.h>
19 /*===========================================================================*
20 * do_cprofile *
21 *===========================================================================*/
22 PUBLIC int do_cprofile(struct proc * caller, message * m_ptr)
24 int proc_nr, i;
25 phys_bytes len;
26 vir_bytes vir_dst;
28 switch (m_ptr->PROF_ACTION) {
30 case PROF_RESET:
32 /* Reset profiling tables. */
34 cprof_ctl_inst.reset = 1;
36 printf("CPROFILE notice: resetting tables:");
38 for (i=0; i<cprof_procs_no; i++) {
40 printf(" %s", cprof_proc_info[i].name);
42 /* Test whether proc still alive. */
43 if (!isokendpt(cprof_proc_info[i].endpt, &proc_nr)) {
44 printf("endpt not valid %u (%s)\n",
45 cprof_proc_info[i].endpt, cprof_proc_info[i].name);
46 continue;
49 /* Set reset flag. */
50 data_copy(KERNEL, (vir_bytes) &cprof_ctl_inst.reset,
51 cprof_proc_info[i].endpt, cprof_proc_info[i].ctl_v,
52 sizeof(cprof_ctl_inst.reset));
54 printf("\n");
56 return OK;
58 case PROF_GET:
60 /* Get profiling data.
62 * Calculate physical addresses of user pointers. Copy to user
63 * program the info struct. Copy to user program the profiling
64 * tables of the profiled processes.
67 if(!isokendpt(m_ptr->PROF_ENDPT, &proc_nr))
68 return EINVAL;
70 cprof_mem_size = m_ptr->PROF_MEM_SIZE;
72 printf("CPROFILE notice: getting tables:");
74 /* Copy control structs of profiled processes to calculate total
75 * nr of bytes to be copied to user program and find out if any
76 * errors happened. */
77 cprof_info.mem_used = 0;
78 cprof_info.err = 0;
80 for (i=0; i<cprof_procs_no; i++) {
82 printf(" %s", cprof_proc_info[i].name);
84 /* Test whether proc still alive. */
85 if (!isokendpt(cprof_proc_info[i].endpt, &proc_nr)) {
86 printf("endpt not valid %u (%s)\n",
87 cprof_proc_info[i].endpt, cprof_proc_info[i].name);
88 continue;
91 /* Copy control struct from proc to local variable. */
92 data_copy(cprof_proc_info[i].endpt, cprof_proc_info[i].ctl_v,
93 KERNEL, (vir_bytes) &cprof_ctl_inst,
94 sizeof(cprof_ctl_inst));
96 /* Calculate memory used. */
97 cprof_proc_info[i].slots_used = cprof_ctl_inst.slots_used;
98 cprof_info.mem_used += CPROF_PROCNAME_LEN;
99 cprof_info.mem_used += sizeof(cprof_proc_info_inst.slots_used);
100 cprof_info.mem_used += cprof_proc_info[i].slots_used *
101 sizeof(cprof_tbl_inst);
102 /* Collect errors. */
103 cprof_info.err |= cprof_ctl_inst.err;
105 printf("\n");
107 /* Do we have the space available? */
108 if (cprof_mem_size < cprof_info.mem_used) cprof_info.mem_used = -1;
110 /* Copy the info struct to the user process. */
111 data_copy(KERNEL, (vir_bytes) &cprof_info,
112 m_ptr->PROF_ENDPT, (vir_bytes) m_ptr->PROF_CTL_PTR,
113 sizeof(cprof_info));
115 /* If there is no space or errors occurred, don't bother copying. */
116 if (cprof_info.mem_used == -1 || cprof_info.err) return OK;
118 /* For each profiled process, copy its name, slots_used and profiling
119 * table to the user process. */
120 vir_dst = (vir_bytes) m_ptr->PROF_MEM_PTR;
121 for (i=0; i<cprof_procs_no; i++) {
122 len = (phys_bytes) strlen(cprof_proc_info[i].name);
123 data_copy(KERNEL, (vir_bytes) cprof_proc_info[i].name,
124 m_ptr->PROF_ENDPT, vir_dst, len);
125 vir_dst += CPROF_PROCNAME_LEN;
127 len = (phys_bytes) sizeof(cprof_ctl_inst.slots_used);
128 data_copy(cprof_proc_info[i].endpt,
129 cprof_proc_info[i].ctl_v + sizeof(cprof_ctl_inst.reset),
130 m_ptr->PROF_ENDPT, vir_dst, len);
131 vir_dst += len;
133 len = (phys_bytes)
134 (sizeof(cprof_tbl_inst) * cprof_proc_info[i].slots_used);
135 data_copy(cprof_proc_info[i].endpt, cprof_proc_info[i].buf_v,
136 m_ptr->PROF_ENDPT, vir_dst, len);
137 vir_dst += len;
140 return OK;
142 default:
143 return EINVAL;