By making m_in job local (i.e., each job has its own copy of m_in instead of refering to the global m_in) we don't have to store and restore m_in on every thread yield. This reduces overhead. Moreover, remove the assumption that m_in is preserved. Do_XXX functions have to copy the system call parameters as soon as possible and only pass those copies to other functions. Furthermore, this patch cleans up some code and uses better types in a lot of places.
67 lines
1.7 KiB
C
67 lines
1.7 KiB
C
|
|
#include "fs.h"
|
|
#include "file.h"
|
|
#include "fproc.h"
|
|
|
|
int gcov_flush(cp_grant_id_t grantid, size_t size );
|
|
|
|
/*===========================================================================*
|
|
* do_gcov_flush *
|
|
*===========================================================================*/
|
|
int do_gcov_flush()
|
|
{
|
|
/* A userland tool has requested the gcov data from another
|
|
* process (possibly vfs itself). Grant the target process
|
|
* access to the supplied buffer, and perform the call that
|
|
* makes the target copy its buffer to the caller (incl vfs
|
|
* itself).
|
|
*/
|
|
struct fproc *rfp;
|
|
ssize_t size;
|
|
cp_grant_id_t grantid;
|
|
int r, n;
|
|
pid_t target;
|
|
message m;
|
|
vir_bytes buf;
|
|
|
|
size = job_m_in.GCOV_BUFF_SZ;
|
|
target = job_m_in.GCOV_PID;
|
|
buf = (vir_bytes) job_m_in.GCOV_BUFF_P;
|
|
|
|
/* If the wrong process is sent to, the system hangs; so make this root-only.
|
|
*/
|
|
|
|
if (!super_user) return(EPERM);
|
|
|
|
/* Find target gcov process. */
|
|
for(n = 0; n < NR_PROCS; n++) {
|
|
if(fproc[n].fp_endpoint != NONE && fproc[n].fp_pid == target)
|
|
break;
|
|
}
|
|
if(n >= NR_PROCS) {
|
|
printf("VFS: gcov process %d not found\n", target);
|
|
return(ESRCH);
|
|
}
|
|
rfp = &fproc[n];
|
|
|
|
/* Grant target process to requestor's buffer. */
|
|
if ((grantid = cpf_grant_magic(rfp->fp_endpoint, who_e, buf,
|
|
size, CPF_WRITE)) < 0) {
|
|
printf("VFS: gcov_flush: grant failed\n");
|
|
return(ENOMEM);
|
|
}
|
|
|
|
if (rfp->fp_endpoint == VFS_PROC_NR) {
|
|
/* Request is for VFS itself. */
|
|
r = gcov_flush(grantid, size);
|
|
} else {
|
|
/* Perform generic GCOV request. */
|
|
m.GCOV_GRANT = grantid;
|
|
m.GCOV_BUFF_SZ = size;
|
|
r = _taskcall(rfp->fp_endpoint, COMMON_REQ_GCOV_DATA, &m);
|
|
}
|
|
|
|
cpf_revoke(grantid);
|
|
|
|
return(r);
|
|
}
|