⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sr.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
	r= (*sr_fd->srf_select)(sr_fd->srf_fd,  i_ops);	if (r < 0)		return r;	m_ops= 0;	if (r & SR_SELECT_READ) m_ops |= SEL_RD;	if (r & SR_SELECT_WRITE) m_ops |= SEL_WR;	if (r & SR_SELECT_EXCEPTION) m_ops |= SEL_ERR;	return m_ops;}PRIVATE void sr_status(m)message *m;{	int fd, result;	unsigned m_ops;	sr_fd_t *sr_fd;	mq_t *mq;	mq= repl_queue;	if (mq != NULL)	{		repl_queue= mq->mq_next;		mq->mq_mess.m_type= DEV_REVIVE;		result= send(mq->mq_mess.m_source, &mq->mq_mess);		if (result != OK)			ip_panic(("unable to send"));		mq_free(mq);		return;	}	for (fd=0, sr_fd= sr_fd_table; fd<FD_NR; fd++, sr_fd++)	{		if ((sr_fd->srf_flags &			(SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X)) == 0)		{			/* Nothing to report */			continue;		}		if (sr_fd->srf_select_proc != m->m_source)		{			/* Wrong process */			continue;		}		m_ops= 0;		if (sr_fd->srf_flags & SFF_SELECT_R) m_ops |= SEL_RD;		if (sr_fd->srf_flags & SFF_SELECT_W) m_ops |= SEL_WR;		if (sr_fd->srf_flags & SFF_SELECT_X) m_ops |= SEL_ERR;		sr_fd->srf_flags &= ~(SFF_SELECT_R|SFF_SELECT_W|SFF_SELECT_X);		m->m_type= DEV_IO_READY;		m->DEV_MINOR= fd;		m->DEV_SEL_OPS= m_ops;		result= send(m->m_source, m);		if (result != OK)			ip_panic(("unable to send"));		return;	}	m->m_type= DEV_NO_STATUS;	result= send(m->m_source, m);	if (result != OK)		ip_panic(("unable to send"));}#endifPRIVATE int walk_queue(sr_fd, q_head_ptr, q_tail_ptr, type, proc_nr, ref,	first_flag)sr_fd_t *sr_fd;mq_t **q_head_ptr;mq_t **q_tail_ptr;int type;int proc_nr;int ref;int first_flag;{	mq_t *q_ptr_prv, *q_ptr;	int result;	for(q_ptr_prv= NULL, q_ptr= *q_head_ptr; q_ptr; 		q_ptr_prv= q_ptr, q_ptr= q_ptr->mq_next)	{		if (q_ptr->mq_mess.NDEV_PROC != proc_nr)			continue;#ifdef __minix_vmd		if (q_ptr->mq_mess.NDEV_REF != ref)			continue;#endif		if (!q_ptr_prv)		{			assert(!(sr_fd->srf_flags & first_flag));			sr_fd->srf_flags |= first_flag;			result= (*sr_fd->srf_cancel)(sr_fd->srf_fd, type);			assert(result == OK);			*q_head_ptr= q_ptr->mq_next;			mq_free(q_ptr);			assert(sr_fd->srf_flags & first_flag);			sr_fd->srf_flags &= ~first_flag;			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];	assert (!(loc_fd->srf_flags & SFF_MINOR) &&		(loc_fd->srf_flags & SFF_INUSE));	return loc_fd;}PRIVATE void sr_reply_(mq, status, is_revive)mq_t *mq;int status;int is_revive;{	int result, proc, ref,operation;	message reply, *mp;	proc= mq->mq_mess.NDEV_PROC;#ifdef __minix_vmd	ref= mq->mq_mess.NDEV_REF;#else /* Minix 3 */	ref= 0;#endif	operation= mq->mq_mess.m_type;#ifdef __minix_vmd	assert(operation != DEV_CANCEL);#endif	if (is_revive)		mp= &mq->mq_mess;	else		mp= &reply;	mp->m_type= DEVICE_REPLY;	mp->REP_PROC_NR= proc;	mp->REP_STATUS= status;#ifdef __minix_vmd	mp->REP_REF= ref;	mp->REP_OPERATION= operation;#endif	if (is_revive)	{		notify(mq->mq_mess.m_source);		result= ELOCKED;	}	else		result= send(mq->mq_mess.m_source, mp);	if (result == ELOCKED && is_revive)	{		mq->mq_next= NULL;		if (repl_queue)			repl_queue_tail->mq_next= mq;		else			repl_queue= mq;		repl_queue_tail= mq;		return;	}	if (result != OK)		ip_panic(("unable to send"));	if (is_revive)		mq_free(mq);}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, *m, *mq;	int ip_flag, susp_flag, first_flag;	int result, suspended, is_revive;	char *src;	acc_t *acc;	event_t *evp;	ev_arg_t arg;	loc_fd= &sr_fd_table[fd];	if (for_ioctl)	{		head_ptr= &loc_fd->srf_ioctl_q;		evp= &loc_fd->srf_ioctl_ev;		ip_flag= SFF_IOCTL_IP;		susp_flag= SFF_IOCTL_SUSP;		first_flag= SFF_IOCTL_FIRST;	}	else	{		head_ptr= &loc_fd->srf_write_q;		evp= &loc_fd->srf_write_ev;		ip_flag= SFF_WRITE_IP;		susp_flag= SFF_WRITE_SUSP;		first_flag= SFF_WRITE_FIRST;	}		assert (loc_fd->srf_flags & ip_flag);	if (!count)	{		m= *head_ptr;		mq= m->mq_next;		*head_ptr= mq;		result= (int)offset;		is_revive= !(loc_fd->srf_flags & first_flag);		sr_reply_(m, result, is_revive);		suspended= (loc_fd->srf_flags & susp_flag);		loc_fd->srf_flags &= ~(ip_flag|susp_flag);		if (suspended)		{			if (mq)			{				arg.ev_ptr= loc_fd;				ev_enqueue(evp, sr_event, arg);			}		}		return NULL;	}	src= (*head_ptr)->mq_mess.NDEV_BUFFER + offset;	result= cp_u2b ((*head_ptr)->mq_mess.NDEV_PROC, 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, *m, *mq;	int ip_flag, susp_flag, first_flag;	int result, suspended, is_revive;	char *dst;	event_t *evp;	ev_arg_t arg;	loc_fd= &sr_fd_table[fd];	if (for_ioctl)	{		head_ptr= &loc_fd->srf_ioctl_q;		evp= &loc_fd->srf_ioctl_ev;		ip_flag= SFF_IOCTL_IP;		susp_flag= SFF_IOCTL_SUSP;		first_flag= SFF_IOCTL_FIRST;	}	else	{		head_ptr= &loc_fd->srf_read_q;		evp= &loc_fd->srf_read_ev;		ip_flag= SFF_READ_IP;		susp_flag= SFF_READ_SUSP;		first_flag= SFF_READ_FIRST;	}			assert (loc_fd->srf_flags & ip_flag);	if (!data)	{		m= *head_ptr;		mq= m->mq_next;		*head_ptr= mq;		result= (int)offset;		is_revive= !(loc_fd->srf_flags & first_flag);		sr_reply_(m, result, is_revive);		suspended= (loc_fd->srf_flags & susp_flag);		loc_fd->srf_flags &= ~(ip_flag|susp_flag);		if (suspended)		{			if (mq)			{				arg.ev_ptr= loc_fd;				ev_enqueue(evp, sr_event, arg);			}		}		return OK;	}	dst= (*head_ptr)->mq_mess.NDEV_BUFFER + offset;	return cp_b2u (data, (*head_ptr)->mq_mess.NDEV_PROC, dst);}#ifndef __minix_vmd /* Minix 3 */PRIVATE void sr_select_res(fd, ops)int fd;unsigned ops;{	sr_fd_t *sr_fd;	sr_fd= &sr_fd_table[fd];		if (ops & SR_SELECT_READ) sr_fd->srf_flags |= SFF_SELECT_R;	if (ops & SR_SELECT_WRITE) sr_fd->srf_flags |= SFF_SELECT_W;	if (ops & SR_SELECT_EXCEPTION) sr_fd->srf_flags |= SFF_SELECT_X;	notify(sr_fd->srf_select_proc);}#endifPRIVATE 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;		result= sr_rwio(m);		if (result == SUSPEND)		{			if (mq)			{				(*tail_ptr)->mq_next= mq;				*tail_ptr= tail;			}			return;		}	}	return;}PRIVATE void sr_event(evp, arg)event_t *evp;ev_arg_t arg;{	sr_fd_t *sr_fd;	int r;	sr_fd= arg.ev_ptr;	if (evp == &sr_fd->srf_write_ev)	{		while(sr_fd->srf_write_q)		{			r= sr_restart_write(sr_fd);			if (r == SUSPEND)				return;		}		return;	}	if (evp == &sr_fd->srf_read_ev)	{		while(sr_fd->srf_read_q)		{			r= sr_restart_read(sr_fd);			if (r == SUSPEND)				return;		}		return;	}	if (evp == &sr_fd->srf_ioctl_ev)	{		while(sr_fd->srf_ioctl_q)		{			r= sr_restart_ioctl(sr_fd);			if (r == SUSPEND)				return;		}		return;	}	ip_panic(("sr_event: unkown event\n"));}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;#ifdef __minix_vmd		cpvec[i].cpv_src= (vir_bytes)src;		cpvec[i].cpv_dst= (vir_bytes)ptr2acc_data(acc);		cpvec[i].cpv_size= size;#else /* Minix 3 */		vir_cp_req[i].count= size;		vir_cp_req[i].src.proc_nr = proc;		vir_cp_req[i].src.segment = D;		vir_cp_req[i].src.offset = (vir_bytes) src;		vir_cp_req[i].dst.proc_nr = this_proc;		vir_cp_req[i].dst.segment = D;		vir_cp_req[i].dst.offset = (vir_bytes) ptr2acc_data(acc);#endif		src += size;		acc= acc->acc_next;		i++;		if (i == CPVEC_NR || acc == NULL)		{#ifdef __minix_vmd			mess.m_type= SYS_VCOPY;			mess.m1_i1= proc;			mess.m1_i2= this_proc;			mess.m1_i3= i;			mess.m1_p1= (char *)cpvec;#else /* Minix 3 */			mess.m_type= SYS_VIRVCOPY;			mess.VCP_VEC_SIZE= i;			mess.VCP_VEC_ADDR= (char *)vir_cp_req;#endif			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;		}	}	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)		{#ifdef __minix_vmd			cpvec[i].cpv_src= (vir_bytes)ptr2acc_data(acc);			cpvec[i].cpv_dst= (vir_bytes)dest;			cpvec[i].cpv_size= size;#else /* Minix 3 */			vir_cp_req[i].src.proc_nr = this_proc;			vir_cp_req[i].src.segment = D;			vir_cp_req[i].src.offset= (vir_bytes)ptr2acc_data(acc);			vir_cp_req[i].dst.proc_nr = proc;			vir_cp_req[i].dst.segment = D;			vir_cp_req[i].dst.offset= (vir_bytes)dest;			vir_cp_req[i].count= size;#endif			i++;		}		dest += size;		acc= acc->acc_next;		if (i == CPVEC_NR || acc == NULL)		{#ifdef __minix_vmd			mess.m_type= SYS_VCOPY;			mess.m1_i1= this_proc;			mess.m1_i2= proc;			mess.m1_i3= i;			mess.m1_p1= (char *)cpvec;#else /* Minix 3 */			mess.m_type= SYS_VIRVCOPY;			mess.VCP_VEC_SIZE= i;			mess.VCP_VEC_ADDR= (char *) vir_cp_req;#endif			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;		}	}	bf_afree(acc_ptr);	return OK;}PRIVATE int sr_repl_queue(proc, ref, operation)int proc;int ref;int operation;{	mq_t *m, *m_cancel, *m_tmp;	int result;	m_cancel= NULL;	for (m= repl_queue; m;)	{#ifdef __minix_vmd		if (m->mq_mess.REP_PROC_NR == proc && 			m->mq_mess.REP_REF ==ref &&			(m->mq_mess.REP_OPERATION == operation ||				operation == CANCEL_ANY))#else /* Minix 3 */		if (m->mq_mess.REP_PROC_NR == proc)#endif		{assert(!m_cancel);			m_cancel= m;			m= m->mq_next;			continue;		}		result= send(m->mq_mess.m_source, &m->mq_mess);		if (result != OK)			ip_panic(("unable to send: %d", result));		m_tmp= m;		m= m->mq_next;		mq_free(m_tmp);	}	repl_queue= NULL;	if (m_cancel)	{		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;}/* * $PchId: sr.c,v 1.17 2005/06/28 14:26:16 philip Exp $ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -