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 "kernel/system.h"
21 static struct cprof_ctl_s cprof_ctl_inst
;
22 static struct cprof_tbl_s cprof_tbl_inst
;
24 /*===========================================================================*
26 *===========================================================================*/
27 int do_cprofile(struct proc
* caller
, message
* m_ptr
)
33 switch (m_ptr
->PROF_ACTION
) {
37 /* Reset profiling tables. */
39 cprof_ctl_inst
.reset
= 1;
41 printf("CPROFILE notice: resetting tables:");
43 for (i
=0; i
<cprof_procs_no
; i
++) {
45 printf(" %s", cprof_proc_info
[i
].name
);
47 /* Test whether proc still alive. */
48 if (!isokendpt(cprof_proc_info
[i
].endpt
, &proc_nr
)) {
49 printf("endpt not valid %u (%s)\n",
50 cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].name
);
55 data_copy(KERNEL
, (vir_bytes
) &cprof_ctl_inst
.reset
,
56 cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].ctl_v
,
57 sizeof(cprof_ctl_inst
.reset
));
65 /* Get profiling data.
67 * Calculate physical addresses of user pointers. Copy to user
68 * program the info struct. Copy to user program the profiling
69 * tables of the profiled processes.
72 if(!isokendpt(m_ptr
->PROF_ENDPT
, &proc_nr
))
75 cprof_mem_size
= m_ptr
->PROF_MEM_SIZE
;
77 printf("CPROFILE notice: getting tables:");
79 /* Copy control structs of profiled processes to calculate total
80 * nr of bytes to be copied to user program and find out if any
82 cprof_info
.mem_used
= 0;
85 for (i
=0; i
<cprof_procs_no
; i
++) {
87 printf(" %s", cprof_proc_info
[i
].name
);
89 /* Test whether proc still alive. */
90 if (!isokendpt(cprof_proc_info
[i
].endpt
, &proc_nr
)) {
91 printf("endpt not valid %u (%s)\n",
92 cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].name
);
96 /* Copy control struct from proc to local variable. */
97 data_copy(cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].ctl_v
,
98 KERNEL
, (vir_bytes
) &cprof_ctl_inst
,
99 sizeof(cprof_ctl_inst
));
101 /* Calculate memory used. */
102 cprof_proc_info
[i
].slots_used
= cprof_ctl_inst
.slots_used
;
103 cprof_info
.mem_used
+= CPROF_PROCNAME_LEN
;
104 cprof_info
.mem_used
+= sizeof(cprof_proc_info_inst
.slots_used
);
105 cprof_info
.mem_used
+= cprof_proc_info
[i
].slots_used
*
106 sizeof(cprof_tbl_inst
);
107 /* Collect errors. */
108 cprof_info
.err
|= cprof_ctl_inst
.err
;
112 /* Do we have the space available? */
113 if (cprof_mem_size
< cprof_info
.mem_used
) cprof_info
.mem_used
= -1;
115 /* Copy the info struct to the user process. */
116 data_copy(KERNEL
, (vir_bytes
) &cprof_info
,
117 m_ptr
->PROF_ENDPT
, (vir_bytes
) m_ptr
->PROF_CTL_PTR
,
120 /* If there is no space or errors occurred, don't bother copying. */
121 if (cprof_info
.mem_used
== -1 || cprof_info
.err
) return OK
;
123 /* For each profiled process, copy its name, slots_used and profiling
124 * table to the user process. */
125 vir_dst
= (vir_bytes
) m_ptr
->PROF_MEM_PTR
;
126 for (i
=0; i
<cprof_procs_no
; i
++) {
127 len
= (phys_bytes
) strlen(cprof_proc_info
[i
].name
);
128 data_copy(KERNEL
, (vir_bytes
) cprof_proc_info
[i
].name
,
129 m_ptr
->PROF_ENDPT
, vir_dst
, len
);
130 vir_dst
+= CPROF_PROCNAME_LEN
;
132 len
= (phys_bytes
) sizeof(cprof_ctl_inst
.slots_used
);
133 data_copy(cprof_proc_info
[i
].endpt
,
134 cprof_proc_info
[i
].ctl_v
+ sizeof(cprof_ctl_inst
.reset
),
135 m_ptr
->PROF_ENDPT
, vir_dst
, len
);
139 (sizeof(cprof_tbl_inst
) * cprof_proc_info
[i
].slots_used
);
140 data_copy(cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].buf_v
,
141 m_ptr
->PROF_ENDPT
, vir_dst
, len
);
152 #endif /* CPROFILE */