1 /* The kernel call that is implemented in this file:
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)
12 * 14 Aug, 2006 Created (Rogier Meurs)
15 #include "../system.h"
19 /*===========================================================================*
21 *===========================================================================*/
22 PUBLIC
int do_cprofile(struct proc
* caller
, message
* m_ptr
)
28 switch (m_ptr
->PROF_ACTION
) {
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
);
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
));
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
))
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
77 cprof_info
.mem_used
= 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
);
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
;
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
,
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
);
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
);