RS: use IPC filters to do a timed receive
Change-Id: I28df9920d8a65b47f3cf974ed9c5eb3174479d8a
This commit is contained in:
parent
fb6bd596bf
commit
f16b761d2a
2 changed files with 56 additions and 4 deletions
|
@ -131,7 +131,7 @@ char* srv_to_string_gen(struct rproc *rp, int is_verbose);
|
|||
char* srv_upd_to_string(struct rprocupd *rpupd);
|
||||
int rs_asynsend(struct rproc *rp, message *m_ptr, int no_reply);
|
||||
int rs_receive_ticks(endpoint_t src, message *m_ptr,
|
||||
int *status_ptr, int ticks);
|
||||
int *status_ptr, clock_t ticks);
|
||||
void reply(endpoint_t who, struct rproc *rp, message *m_ptr);
|
||||
void late_reply(struct rproc *rp, int code);
|
||||
int rs_isokendpt(endpoint_t endpoint, int *proc);
|
||||
|
|
|
@ -219,10 +219,62 @@ int rs_asynsend(struct rproc *rp, message *m_ptr, int no_reply)
|
|||
* rs_receive_ticks *
|
||||
*===========================================================================*/
|
||||
int rs_receive_ticks(endpoint_t src, message *m_ptr,
|
||||
int *status_ptr, int ticks)
|
||||
int *status_ptr, clock_t ticks)
|
||||
{
|
||||
printf("RS: rs_receive_ticks not implemented\n");
|
||||
return ENOSYS;
|
||||
/* IPC receive with timeout. Implemented with IPC filters. The timer
|
||||
* management logic comes from the tickdelay(3) implementation.
|
||||
*/
|
||||
ipc_filter_el_t ipc_filter[2];
|
||||
clock_t time_left, uptime;
|
||||
int r, s, status;
|
||||
|
||||
/* Use IPC filters to receive from the provided source and CLOCK only.
|
||||
* We make the hard assumption that RS did not already have IPC filters set.
|
||||
*/
|
||||
memset(ipc_filter, 0, sizeof(ipc_filter));
|
||||
ipc_filter[0].flags = IPCF_MATCH_M_SOURCE;
|
||||
ipc_filter[0].m_source = CLOCK;
|
||||
ipc_filter[1].flags = IPCF_MATCH_M_SOURCE;
|
||||
ipc_filter[1].m_source = src;
|
||||
|
||||
if ((s = sys_statectl(SYS_STATE_ADD_IPC_WL_FILTER, ipc_filter,
|
||||
sizeof(ipc_filter))) != OK)
|
||||
panic("RS: rs_receive_ticks: setting IPC filter failed: %d", s);
|
||||
|
||||
/* Set a new alarm, and get information about the previous alarm. */
|
||||
if ((s = sys_setalarm2(ticks, FALSE, &time_left, &uptime)) != OK)
|
||||
panic("RS: rs_receive_ticks: setting alarm failed: %d", s);
|
||||
|
||||
/* Receive a message from either the provided source or CLOCK. */
|
||||
while ((r = ipc_receive(ANY, m_ptr, &status)) == OK &&
|
||||
m_ptr->m_source == CLOCK) {
|
||||
/* Ignore early clock notifications. */
|
||||
if (m_ptr->m_type == NOTIFY_MESSAGE &&
|
||||
m_ptr->m_notify.timestamp >= uptime + ticks)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reinstate the previous alarm, if any. Do this in any case. */
|
||||
if (time_left != TMR_NEVER) {
|
||||
if (time_left > ticks)
|
||||
time_left -= ticks;
|
||||
else
|
||||
time_left = 1; /* force an alarm */
|
||||
|
||||
(void)sys_setalarm(time_left, FALSE);
|
||||
}
|
||||
|
||||
/* Clear the IPC filters. */
|
||||
if ((s = sys_statectl(SYS_STATE_CLEAR_IPC_FILTERS, NULL, 0)) != OK)
|
||||
panic("RS: rs_receive_ticks: setting IPC filter failed: %d", s);
|
||||
|
||||
/* If the last received message was from CLOCK, we timed out. */
|
||||
if (r == OK && m_ptr->m_source == CLOCK)
|
||||
return ENOTREADY;
|
||||
|
||||
if (status_ptr != NULL)
|
||||
*status_ptr = status;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
Loading…
Reference in a new issue