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"
21 /*===========================================================================*
23 *===========================================================================*/
24 PUBLIC
int do_cprofile(m_ptr
)
25 register message
*m_ptr
; /* pointer to request message */
27 int proc_nr
, i
, err
= 0, k
= 0;
29 phys_bytes phys_src
, phys_dst
, len
;
31 switch (m_ptr
->PROF_ACTION
) {
35 /* Reset profiling tables. */
37 cprof_ctl_inst
.reset
= 1;
39 kprintf("CPROFILE notice: resetting tables:");
41 for (i
=0; i
<cprof_procs_no
; i
++) {
43 kprintf(" %s", cprof_proc_info
[i
].name
);
45 /* Test whether proc still alive. */
46 if (!isokendpt(cprof_proc_info
[i
].endpt
, &proc_nr
)) {
47 kprintf("endpt not valid %u (%s)\n",
48 cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].name
);
53 phys_src
= vir2phys((vir_bytes
) &cprof_ctl_inst
.reset
);
54 phys_dst
= (phys_bytes
) cprof_proc_info
[i
].ctl
;
55 len
= (phys_bytes
) sizeof(cprof_ctl_inst
.reset
);
56 phys_copy(phys_src
, phys_dst
, len
);
64 /* Get profiling data.
66 * Calculate physical addresses of user pointers. Copy to user
67 * program the info struct. Copy to user program the profiling
68 * tables of the profiled processes.
71 if(!isokendpt(m_ptr
->PROF_ENDPT
, &proc_nr
))
74 vir_dst
= (vir_bytes
) m_ptr
->PROF_CTL_PTR
;
75 len
= (phys_bytes
) sizeof (int *);
76 cprof_info_addr
= numap_local(proc_nr
, vir_dst
, len
);
78 vir_dst
= (vir_bytes
) m_ptr
->PROF_MEM_PTR
;
79 len
= (phys_bytes
) sizeof (char *);
80 cprof_data_addr
= numap_local(proc_nr
, vir_dst
, len
);
82 cprof_mem_size
= m_ptr
->PROF_MEM_SIZE
;
84 kprintf("CPROFILE notice: getting tables:");
86 /* Copy control structs of profiled processes to calculate total
87 * nr of bytes to be copied to user program and find out if any
89 cprof_info
.mem_used
= 0;
92 for (i
=0; i
<cprof_procs_no
; i
++) {
94 kprintf(" %s", cprof_proc_info
[i
].name
);
96 /* Test whether proc still alive. */
97 if (!isokendpt(cprof_proc_info
[i
].endpt
, &proc_nr
)) {
98 kprintf("endpt not valid %u (%s)\n",
99 cprof_proc_info
[i
].endpt
, cprof_proc_info
[i
].name
);
103 /* Copy control struct from proc to local variable. */
104 phys_src
= cprof_proc_info
[i
].ctl
;
105 phys_dst
= vir2phys((vir_bytes
) &cprof_ctl_inst
);
106 len
= (phys_bytes
) sizeof(cprof_ctl_inst
);
107 phys_copy(phys_src
, phys_dst
, len
);
109 /* Calculate memory used. */
110 cprof_proc_info
[i
].slots_used
= cprof_ctl_inst
.slots_used
;
111 cprof_info
.mem_used
+= CPROF_PROCNAME_LEN
;
112 cprof_info
.mem_used
+= sizeof(cprof_proc_info_inst
.slots_used
);
113 cprof_info
.mem_used
+= cprof_proc_info
[i
].slots_used
*
114 sizeof(cprof_tbl_inst
);
115 /* Collect errors. */
116 cprof_info
.err
|= cprof_ctl_inst
.err
;
120 /* Do we have the space available? */
121 if (cprof_mem_size
< cprof_info
.mem_used
) cprof_info
.mem_used
= -1;
123 /* Copy the info struct to the user process. */
124 phys_copy(vir2phys((vir_bytes
) &cprof_info
), cprof_info_addr
,
125 (phys_bytes
) sizeof(cprof_info
));
127 /* If there is no space or errors occurred, don't bother copying. */
128 if (cprof_info
.mem_used
== -1 || cprof_info
.err
) return OK
;
130 /* For each profiled process, copy its name, slots_used and profiling
131 * table to the user process. */
132 phys_dst
= cprof_data_addr
;
133 for (i
=0; i
<cprof_procs_no
; i
++) {
134 phys_src
= vir2phys((vir_bytes
) cprof_proc_info
[i
].name
);
135 len
= (phys_bytes
) strlen(cprof_proc_info
[i
].name
);
136 phys_copy(phys_src
, phys_dst
, len
);
137 phys_dst
+= CPROF_PROCNAME_LEN
;
139 phys_src
= cprof_proc_info
[i
].ctl
+
140 sizeof(cprof_ctl_inst
.reset
);
141 len
= (phys_bytes
) sizeof(cprof_ctl_inst
.slots_used
);
142 phys_copy(phys_src
, phys_dst
, len
);
145 phys_src
= cprof_proc_info
[i
].buf
;
147 (sizeof(cprof_tbl_inst
) * cprof_proc_info
[i
].slots_used
);
148 phys_copy(phys_src
, phys_dst
, len
);
159 #endif /* CPROFILE */