Add ipc messages, signals, context switches usage
Add ipc messages, signals, context switches usage to kernel
This commit is contained in:
parent
ea85fc5989
commit
85c3fce1a7
|
|
@ -61,6 +61,9 @@ static int try_one(struct proc *src_ptr, struct proc *dst_ptr);
|
||||||
static struct proc * pick_proc(void);
|
static struct proc * pick_proc(void);
|
||||||
static void enqueue_head(struct proc *rp);
|
static void enqueue_head(struct proc *rp);
|
||||||
|
|
||||||
|
static void increase_context_switch_count(struct proc *rp);
|
||||||
|
static void increase_messages_count(struct proc *from, struct proc *to);
|
||||||
|
|
||||||
/* all idles share the same idle_priv structure */
|
/* all idles share the same idle_priv structure */
|
||||||
static struct priv idle_priv;
|
static struct priv idle_priv;
|
||||||
|
|
||||||
|
|
@ -129,6 +132,7 @@ void proc_init(void)
|
||||||
rp->p_scheduler = NULL; /* no user space scheduler */
|
rp->p_scheduler = NULL; /* no user space scheduler */
|
||||||
rp->p_priority = 0; /* no priority */
|
rp->p_priority = 0; /* no priority */
|
||||||
rp->p_quantum_size_ms = 0; /* no quantum size */
|
rp->p_quantum_size_ms = 0; /* no quantum size */
|
||||||
|
reset_proc_rusage(rp);
|
||||||
|
|
||||||
/* arch-specific initialization */
|
/* arch-specific initialization */
|
||||||
arch_proc_reset(rp);
|
arch_proc_reset(rp);
|
||||||
|
|
@ -807,6 +811,7 @@ int mini_send(
|
||||||
* for this message, copy the message to it and unblock 'dst'. If 'dst' is
|
* for this message, copy the message to it and unblock 'dst'. If 'dst' is
|
||||||
* not waiting at all, or is waiting for another source, queue 'caller_ptr'.
|
* not waiting at all, or is waiting for another source, queue 'caller_ptr'.
|
||||||
*/
|
*/
|
||||||
|
int res = OK;
|
||||||
register struct proc *dst_ptr;
|
register struct proc *dst_ptr;
|
||||||
register struct proc **xpp;
|
register struct proc **xpp;
|
||||||
int dst_p;
|
int dst_p;
|
||||||
|
|
@ -815,7 +820,8 @@ int mini_send(
|
||||||
|
|
||||||
if (RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT))
|
if (RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT))
|
||||||
{
|
{
|
||||||
return EDEADSRCDST;
|
res = EDEADSRCDST;
|
||||||
|
goto update_rusage_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if 'dst' is blocked waiting for this message. The destination's
|
/* Check if 'dst' is blocked waiting for this message. The destination's
|
||||||
|
|
@ -827,8 +833,10 @@ int mini_send(
|
||||||
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
|
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||||
|
|
||||||
if (!(flags & FROM_KERNEL)) {
|
if (!(flags & FROM_KERNEL)) {
|
||||||
if(copy_msg_from_user(m_ptr, &dst_ptr->p_delivermsg))
|
if (copy_msg_from_user(m_ptr, &dst_ptr->p_delivermsg)) {
|
||||||
return EFAULT;
|
res = EFAULT;
|
||||||
|
goto update_rusage_and_exit;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dst_ptr->p_delivermsg = *m_ptr;
|
dst_ptr->p_delivermsg = *m_ptr;
|
||||||
IPC_STATUS_ADD_FLAGS(dst_ptr, IPC_FLG_MSG_FROM_KERNEL);
|
IPC_STATUS_ADD_FLAGS(dst_ptr, IPC_FLG_MSG_FROM_KERNEL);
|
||||||
|
|
@ -851,19 +859,23 @@ int mini_send(
|
||||||
hook_ipc_msgrecv(&dst_ptr->p_delivermsg, caller_ptr, dst_ptr);
|
hook_ipc_msgrecv(&dst_ptr->p_delivermsg, caller_ptr, dst_ptr);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if(flags & NON_BLOCKING) {
|
if (flags & NON_BLOCKING) {
|
||||||
return(ENOTREADY);
|
res = ENOTREADY;
|
||||||
|
goto update_rusage_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a possible deadlock before actually blocking. */
|
/* Check for a possible deadlock before actually blocking. */
|
||||||
if (deadlock(SEND, caller_ptr, dst_e)) {
|
if (deadlock(SEND, caller_ptr, dst_e)) {
|
||||||
return(ELOCKED);
|
res = ELOCKED;
|
||||||
|
goto update_rusage_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destination is not waiting. Block and dequeue caller. */
|
/* Destination is not waiting. Block and dequeue caller. */
|
||||||
if (!(flags & FROM_KERNEL)) {
|
if (!(flags & FROM_KERNEL)) {
|
||||||
if(copy_msg_from_user(m_ptr, &caller_ptr->p_sendmsg))
|
if (copy_msg_from_user(m_ptr, &caller_ptr->p_sendmsg)) {
|
||||||
return EFAULT;
|
res = EFAULT;
|
||||||
|
goto update_rusage_and_exit;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
caller_ptr->p_sendmsg = *m_ptr;
|
caller_ptr->p_sendmsg = *m_ptr;
|
||||||
/*
|
/*
|
||||||
|
|
@ -887,7 +899,15 @@ int mini_send(
|
||||||
hook_ipc_msgsend(&caller_ptr->p_sendmsg, caller_ptr, dst_ptr);
|
hook_ipc_msgsend(&caller_ptr->p_sendmsg, caller_ptr, dst_ptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return(OK);
|
|
||||||
|
update_rusage_and_exit:
|
||||||
|
/* When message is not actually delivered we set dst_ptr to
|
||||||
|
* NULL so it's rusage won't be updated*/
|
||||||
|
if (res != OK)
|
||||||
|
dst_ptr = NULL;
|
||||||
|
|
||||||
|
increase_messages_count(caller_ptr, dst_ptr);
|
||||||
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
|
@ -1057,6 +1077,7 @@ int mini_notify(
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_ptr = proc_addr(dst_p);
|
dst_ptr = proc_addr(dst_p);
|
||||||
|
increase_messages_count(caller_ptr, dst_ptr);
|
||||||
|
|
||||||
/* Check to see if target is blocked waiting for this message. A process
|
/* Check to see if target is blocked waiting for this message. A process
|
||||||
* can be both sending and receiving during a SENDREC system call.
|
* can be both sending and receiving during a SENDREC system call.
|
||||||
|
|
@ -1211,6 +1232,9 @@ int try_deliver_senda(struct proc *caller_ptr,
|
||||||
r = EDEADSRCDST;
|
r = EDEADSRCDST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r == OK)
|
||||||
|
increase_messages_count(caller_ptr, dst_ptr);
|
||||||
|
|
||||||
/* Check if 'dst' is blocked waiting for this message.
|
/* Check if 'dst' is blocked waiting for this message.
|
||||||
* If AMF_NOREPLY is set, do not satisfy the receiving part of
|
* If AMF_NOREPLY is set, do not satisfy the receiving part of
|
||||||
* a SENDREC.
|
* a SENDREC.
|
||||||
|
|
@ -1686,6 +1710,8 @@ void dequeue(struct proc *rp)
|
||||||
/* Process accounting for scheduling */
|
/* Process accounting for scheduling */
|
||||||
rp->p_accounting.dequeues++;
|
rp->p_accounting.dequeues++;
|
||||||
|
|
||||||
|
increase_context_switch_count(rp);
|
||||||
|
|
||||||
/* this is not all that accurate on virtual machines, especially with
|
/* this is not all that accurate on virtual machines, especially with
|
||||||
IO bound processes that only spend a short amount of time in the queue
|
IO bound processes that only spend a short amount of time in the queue
|
||||||
at a time. */
|
at a time. */
|
||||||
|
|
@ -1906,3 +1932,34 @@ void ser_dump_proc()
|
||||||
print_proc_recursive(pp);
|
print_proc_recursive(pp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_proc_rusage(struct proc *p)
|
||||||
|
{
|
||||||
|
p->p_voluntary_context_switch = 0;
|
||||||
|
p->p_involuntary_context_switch = 0;
|
||||||
|
p->p_signal_received = 0;
|
||||||
|
p->p_message_sent = 0;
|
||||||
|
p->p_message_received = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increase_context_switch_count(struct proc *rp)
|
||||||
|
{
|
||||||
|
assert(!proc_is_runnable(rp));
|
||||||
|
if (RTS_ISSET(rp, RTS_PREEMPTED) || RTS_ISSET(rp, RTS_NO_QUANTUM))
|
||||||
|
rp->p_involuntary_context_switch++;
|
||||||
|
else
|
||||||
|
rp->p_voluntary_context_switch++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increase_proc_signals(struct proc *p)
|
||||||
|
{
|
||||||
|
p->p_signal_received++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increase_messages_count(struct proc *from, struct proc *to)
|
||||||
|
{
|
||||||
|
if (from)
|
||||||
|
from->p_message_sent++;
|
||||||
|
if (to)
|
||||||
|
to->p_message_received++;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,12 @@ struct proc {
|
||||||
*/
|
*/
|
||||||
struct { reg_t r1, r2, r3; } p_defer;
|
struct { reg_t r1, r2, r3; } p_defer;
|
||||||
|
|
||||||
|
u64_t p_message_sent;
|
||||||
|
u64_t p_message_received;
|
||||||
|
u64_t p_signal_received;
|
||||||
|
u64_t p_voluntary_context_switch;
|
||||||
|
u64_t p_involuntary_context_switch;
|
||||||
|
|
||||||
#if DEBUG_TRACE
|
#if DEBUG_TRACE
|
||||||
int p_schedules;
|
int p_schedules;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,8 @@ int isokendpt_f(endpoint_t e, int *p, int f);
|
||||||
#endif
|
#endif
|
||||||
void proc_no_time(struct proc *p);
|
void proc_no_time(struct proc *p);
|
||||||
void reset_proc_accounting(struct proc *p);
|
void reset_proc_accounting(struct proc *p);
|
||||||
|
void reset_proc_rusage(struct proc *p);
|
||||||
|
void increase_proc_signals(struct proc *p);
|
||||||
void flag_account(struct proc *p, int flag);
|
void flag_account(struct proc *p, int flag);
|
||||||
int try_deliver_senda(struct proc *caller_ptr, asynmsg_t *table, size_t
|
int try_deliver_senda(struct proc *caller_ptr, asynmsg_t *table, size_t
|
||||||
size);
|
size);
|
||||||
|
|
|
||||||
|
|
@ -373,6 +373,7 @@ int send_sig(endpoint_t ep, int sig_nr)
|
||||||
priv = priv(rp);
|
priv = priv(rp);
|
||||||
if(!priv) return ENOENT;
|
if(!priv) return ENOENT;
|
||||||
sigaddset(&priv->s_sig_pending, sig_nr);
|
sigaddset(&priv->s_sig_pending, sig_nr);
|
||||||
|
increase_proc_signals(rp);
|
||||||
mini_notify(proc_addr(SYSTEM), rp->p_endpoint);
|
mini_notify(proc_addr(SYSTEM), rp->p_endpoint);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
@ -434,6 +435,7 @@ int sig_nr; /* signal to be sent */
|
||||||
/* Check if the signal is already pending. Process it otherwise. */
|
/* Check if the signal is already pending. Process it otherwise. */
|
||||||
if (! sigismember(&rp->p_pending, sig_nr)) {
|
if (! sigismember(&rp->p_pending, sig_nr)) {
|
||||||
sigaddset(&rp->p_pending, sig_nr);
|
sigaddset(&rp->p_pending, sig_nr);
|
||||||
|
increase_proc_signals(rp);
|
||||||
if (! (RTS_ISSET(rp, RTS_SIGNALED))) { /* other pending */
|
if (! (RTS_ISSET(rp, RTS_SIGNALED))) { /* other pending */
|
||||||
RTS_SET(rp, RTS_SIGNALED | RTS_SIG_PENDING);
|
RTS_SET(rp, RTS_SIGNALED | RTS_SIG_PENDING);
|
||||||
if(OK != send_sig(sig_mgr, SIGKSIG))
|
if(OK != send_sig(sig_mgr, SIGKSIG))
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ int do_fork(struct proc * caller, message * m_ptr)
|
||||||
make_zero64(rpc->p_kcall_cycles);
|
make_zero64(rpc->p_kcall_cycles);
|
||||||
make_zero64(rpc->p_kipc_cycles);
|
make_zero64(rpc->p_kipc_cycles);
|
||||||
|
|
||||||
|
reset_proc_rusage(rpc);
|
||||||
|
|
||||||
/* If the parent is a privileged process, take away the privileges from the
|
/* If the parent is a privileged process, take away the privileges from the
|
||||||
* child process and inhibit it from running by setting the NO_PRIV flag.
|
* child process and inhibit it from running by setting the NO_PRIV flag.
|
||||||
* The caller should explicitely set the new privileges before executing.
|
* The caller should explicitely set the new privileges before executing.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user