📄 sr.c
字号:
{
if (q_ptr->mq_mess.PROC_NR != proc_nr)
continue;
if (!q_ptr_prv)
{
#if DEBUG & 256
{ where(); printf("calling 0x%x(%d, %d)\n", sr_fd->srf_cancel, sr_fd->srf_fd,
type); }
#endif
result= (*sr_fd->srf_cancel)(sr_fd->srf_fd, type);
assert(result == OK);
return OK;
}
q_ptr_prv->mq_next= q_ptr->mq_next;
mq_free(q_ptr);
if (!q_ptr_prv->mq_next)
*q_tail_ptr= q_ptr_prv;
return EINTR;
}
return EAGAIN;
}
PRIVATE sr_fd_t *sr_getchannel(minor)
int minor;
{
sr_fd_t *loc_fd;
compare(minor, >=, 0);
compare(minor, <, FD_NR);
loc_fd= &sr_fd_table[minor];
#if DEBUG
if ((loc_fd->srf_flags & SFF_MINOR) || !(loc_fd->srf_flags & SFF_INUSE))
{ where(); printf("got req for ill minor (= %d)\n", minor); }
#endif
assert (!(loc_fd->srf_flags & SFF_MINOR) && (loc_fd->srf_flags & SFF_INUSE));
return loc_fd;
}
PRIVATE void sr_reply (mess_ptr, status)
message *mess_ptr;
int status;
{
static message reply;
int result;
#if DEBUG & 256
{ where(); printf("replying %d to %d for proc %d\n", status,
mess_ptr->m_source, mess_ptr->PROC_NR); }
#endif
reply.m_type= REVIVE; /* There no use for TASK_REPLY */
reply.REP_PROC_NR= mess_ptr->PROC_NR;
reply.REP_STATUS= status;
#if DEBUG & 256
{ where(); printf("sending %d to %d for %d\n", reply.m_type,
mess_ptr->m_source, reply.REP_PROC_NR); }
#endif
assert(mess_ptr->m_source != MM_PROC_NR);
result= send (mess_ptr->m_source, &reply);
if (result != OK)
ip_panic(("unable to send"));
}
PRIVATE acc_t *sr_get_userdata (fd, offset, count, for_ioctl)
int fd;
vir_bytes offset;
vir_bytes count;
int for_ioctl;
{
sr_fd_t *loc_fd;
mq_t **head_ptr, **tail_ptr, *m, *tail, *mq;
int ip_flag, susp_flag;
int result;
int suspended;
char *src;
acc_t *acc;
#if DEBUG & 256
{ where(); printf("sr_get_userdata(%d, %u, %u, %d)\n",
fd, offset, count, for_ioctl); }
#endif
loc_fd= &sr_fd_table[fd];
if (for_ioctl)
{
head_ptr= &loc_fd->srf_ioctl_q;
tail_ptr= &loc_fd->srf_ioctl_q_tail;
ip_flag= SFF_IOCTL_IP;
susp_flag= SFF_IOCTL_SUSP;
}
else
{
head_ptr= &loc_fd->srf_write_q;
tail_ptr= &loc_fd->srf_write_q_tail;
ip_flag= SFF_WRITE_IP;
susp_flag= SFF_WRITE_SUSP;
}
assert (loc_fd->srf_flags & ip_flag);
if (!count)
{
m= *head_ptr;
*head_ptr= NULL;
tail= *tail_ptr;
assert(m);
mq= m->mq_next;
result= (int)offset;
sr_revive (m, result);
suspended= (loc_fd->srf_flags & susp_flag);
loc_fd->srf_flags &= ~(ip_flag|susp_flag);
if (suspended)
{
process_req_q(mq, tail, tail_ptr);
}
else
{
assert(!mq);
}
return NULL;
}
src= (*head_ptr)->mq_mess.ADDRESS + offset;
result= cp_u2b ((*head_ptr)->mq_mess.PROC_NR, src, &acc, count);
return result<0 ? NULL : acc;
}
PRIVATE int sr_put_userdata (fd, offset, data, for_ioctl)
int fd;
vir_bytes offset;
acc_t *data;
int for_ioctl;
{
sr_fd_t *loc_fd;
mq_t **head_ptr, **tail_ptr, *m, *tail, *mq;
int ip_flag, susp_flag;
int result;
int suspended;
char *dst;
#if DEBUG & 256
{ where(); printf("sr_put_userdata(%d, %u, 0x%x, %d)\n",
fd, offset, data, for_ioctl); }
#endif
loc_fd= &sr_fd_table[fd];
if (for_ioctl)
{
head_ptr= &loc_fd->srf_ioctl_q;
tail_ptr= &loc_fd->srf_ioctl_q_tail;
ip_flag= SFF_IOCTL_IP;
susp_flag= SFF_IOCTL_SUSP;
}
else
{
head_ptr= &loc_fd->srf_read_q;
tail_ptr= &loc_fd->srf_read_q_tail;
ip_flag= SFF_READ_IP;
susp_flag= SFF_READ_SUSP;
}
assert (loc_fd->srf_flags & ip_flag);
if (!data)
{
m= *head_ptr;
*head_ptr= NULL;
tail= *tail_ptr;
assert(m);
mq= m->mq_next;
result= (int)offset;
sr_revive (m, result);
suspended= (loc_fd->srf_flags & susp_flag);
loc_fd->srf_flags &= ~(ip_flag|susp_flag);
if (suspended)
{
process_req_q(mq, tail, tail_ptr);
}
else
{
assert(!mq);
}
return OK;
}
dst= (*head_ptr)->mq_mess.ADDRESS + offset;
return cp_b2u (data, (*head_ptr)->mq_mess.PROC_NR, dst);
}
PRIVATE void sr_revive (m, status)
mq_t *m;
int status;
{
static message reply;
int result;
#if DEBUG & 256
{ where(); printf("sr_revive: replying %d to %d for proc %d\n", status,
m->mq_mess.m_source, m->mq_mess.PROC_NR); }
#endif
reply.m_type= REVIVE;
reply.REP_PROC_NR= m->mq_mess.PROC_NR;
reply.REP_STATUS= status;
#if DEBUG & 256
{ where(); printf("sending %d to %d for %d\n", reply.m_type,
m->mq_mess.m_source, reply.REP_PROC_NR); }
#endif
assert(m->mq_mess.m_source != MM_PROC_NR);
result= send (m->mq_mess.m_source, &reply);
if (result<0)
{
if (result == ELOCKED)
{
#if DEBUG
{ where(); printf("send locked\n"); }
#endif
reply.m_source= m->mq_mess.m_source;
m->mq_mess= reply;
if (repl_queue)
repl_queue_tail->mq_next= m;
else
repl_queue= m;
repl_queue_tail= m;
return;
}
else
ip_panic(("unable to send"));
}
mq_free(m);
}
PRIVATE void process_req_q(mq, tail, tail_ptr)
mq_t *mq, *tail, **tail_ptr;
{
mq_t *m;
int result;
for(;mq;)
{
m= mq;
mq= mq->mq_next;
#if DEBUG
{ where(); printf("calling rwio\n"); }
#endif
result= sr_rwio(m);
if (result == SUSPEND)
{
if (mq)
{
(*tail_ptr)->mq_next= mq;
*tail_ptr= tail;
}
return;
}
}
return;
}
PRIVATE int cp_u2b (proc, src, var_acc_ptr, size)
int proc;
char *src;
acc_t **var_acc_ptr;
int size;
{
static message mess;
acc_t *acc;
int i;
acc= bf_memreq(size);
*var_acc_ptr= acc;
i=0;
while (acc)
{
size= (vir_bytes)acc->acc_length;
cpvec[i].cpv_src= (vir_bytes)src;
cpvec[i].cpv_dst= (vir_bytes)ptr2acc_data(acc);
cpvec[i].cpv_size= size;
src += size;
acc= acc->acc_next;
i++;
if (i == CPVEC_NR)
{
mess.m_type= SYS_VCOPY;
mess.m1_i1= proc;
mess.m1_i2= THIS_PROC;
mess.m1_i3= i;
mess.m1_p1= (char *)cpvec;
if (sendrec(SYSTASK, &mess) <0)
ip_panic(("unable to sendrec"));
if (mess.m_type <0)
{
bf_afree(*var_acc_ptr);
*var_acc_ptr= 0;
return mess.m_type;
}
i= 0;
}
}
if (i)
{
mess.m_type= SYS_VCOPY;
mess.m1_i1= proc;
mess.m1_i2= THIS_PROC;
mess.m1_i3= i;
mess.m1_p1= (char *)cpvec;
if (sendrec(SYSTASK, &mess) <0)
ip_panic(("unable to sendrec"));
if (mess.m_type <0)
{
bf_afree(*var_acc_ptr);
*var_acc_ptr= 0;
return mess.m_type;
}
}
return OK;
}
PRIVATE int cp_b2u (acc_ptr, proc, dest)
acc_t *acc_ptr;
int proc;
char *dest;
{
static message mess;
acc_t *acc;
int i, size;
acc= acc_ptr;
i=0;
while (acc)
{
size= (vir_bytes)acc->acc_length;
if (size)
{
cpvec[i].cpv_src= (vir_bytes)ptr2acc_data(acc);
cpvec[i].cpv_dst= (vir_bytes)dest;
cpvec[i].cpv_size= size;
i++;
}
dest += size;
acc= acc->acc_next;
if (i == CPVEC_NR)
{
mess.m_type= SYS_VCOPY;
mess.m1_i1= THIS_PROC;
mess.m1_i2= proc;
mess.m1_i3= i;
mess.m1_p1= (char *)cpvec;
if (sendrec(SYSTASK, &mess) <0)
ip_panic(("unable to sendrec"));
if (mess.m_type <0)
{
bf_afree(acc_ptr);
return mess.m_type;
}
i= 0;
}
}
if (i)
{
mess.m_type= SYS_VCOPY;
mess.m1_i1= THIS_PROC;
mess.m1_i2= proc;
mess.m1_i3= i;
mess.m1_p1= (char *)cpvec;
if (sendrec(SYSTASK, &mess) <0)
ip_panic(("unable to sendrec"));
if (mess.m_type <0)
{
bf_afree(acc_ptr);
return mess.m_type;
}
}
bf_afree(acc_ptr);
return OK;
}
PRIVATE int sr_repl_queue(proc)
int proc;
{
mq_t *m, *m_cancel, *tmp;
int result;
m_cancel= NULL;
for (m= repl_queue; m;)
{
if (m->mq_mess.REP_PROC_NR == proc)
{
assert(!m_cancel);
m_cancel= m;
m= m->mq_next;
continue;
}
assert(m->mq_mess.m_source != MM_PROC_NR);
result= send(m->mq_mess.m_source, &m->mq_mess);
if (result != OK)
ip_panic(("unable to send: %d", result));
tmp= m;
m= m->mq_next;
mq_free(tmp);
}
repl_queue= NULL;
if (m_cancel)
{
assert(m_cancel->mq_mess.m_source != MM_PROC_NR);
result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess);
if (result != OK)
ip_panic(("unable to send: %d", result));
mq_free(m_cancel);
return 1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -