plan 9 kernel history: overview | file list | diff list

2001/0619/port/qio.c (diff list | history)

2001/0602/sys/src/9/port/qio.c:865,8702001/0619/sys/src/9/port/qio.c:865,932 (short | long | prev | next)
Add bl2mem, mem2bl. XXX more.
rsc Fri Mar 4 12:44:25 2005
2001/0128    
} 
1993/0528    
 
2001/0128    
/* 
2001/0619    
 *  copy the contents of a string of blocks into 
 *  memory.  emptied blocks are freed.  return 
 *  pointer to first unconsumed block. 
 */ 
Block* 
bl2mem(uchar *p, Block *b, int n) 
{ 
	int i; 
	Block *next; 
 
	for(; b != nil; b = next){ 
		i = BLEN(b); 
		if(i > n){ 
			memmove(p, b->rp, n); 
			b->rp += n; 
			return b; 
		} 
		memmove(p, b->rp, i); 
		n -= i; 
		p += i; 
		b->rp += i; 
		next = b->next; 
		freeb(b); 
	} 
	return nil; 
} 
 
/* 
 *  copy the contents of memory into a string of blocks. 
 *  return nil on error. 
 */ 
Block* 
mem2bl(uchar *p, int len) 
{ 
	int n; 
	Block *b, *first, **l; 
 
	first = nil; 
	l = &first; 
	if(waserror()){ 
		freeblist(first); 
		nexterror(); 
	} 
	do { 
		n = len; 
		if(n > Maxatomic) 
			n = Maxatomic; 
 
		*l = b = allocb(n); 
		setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); 
		memmove(b->wp, p, n); 
		b->wp += n; 
		p += n; 
		len -= n; 
		l = &b->next; 
	} while(len > 0); 
	poperror(); 
 
	return first; 
} 
 
/* 
2001/0128    
 *  put a block back to the front of the queue 
 *  called with q ilocked 
 */ 
2001/0602/sys/src/9/port/qio.c:965,9772001/0619/sys/src/9/port/qio.c:1027,1035
1995/0714    
long 
qread(Queue *q, void *vp, int len) 
{ 
2001/0128    
	Block *b, *first, *next, **l; 
2001/0203    
	int m; 
	uchar *s, *e, *p; 
2001/0619    
	Block *b, *first, **l; 
	int m, n; 
1995/0714    
 
2001/0203    
	s = p = vp; 
	e = s+len; 
                 
2001/0128    
	qlock(&q->rlock); 
	if(waserror()){ 
		qunlock(&q->rlock); 
2001/0602/sys/src/9/port/qio.c:1006,10512001/0619/sys/src/9/port/qio.c:1064,1097
2001/0128    
		 *  following blocks as will completely 
		 *  fit in the read. 
		 */ 
2001/0619    
		n = 0; 
2001/0128    
		l = &first; 
2001/0127    
		m = BLEN(b); 
2001/0128    
		for(;;) { 
			*l = qremove(q); 
			l = &b->next; 
2001/0203    
			p += m; 
2001/0619    
			n += m; 
2001/0203    
 
2001/0128    
			b = q->bfirst; 
			if(b == nil) 
				break; 
			m = BLEN(b); 
2001/0203    
			if(p+m > e) 
2001/0619    
			if(n+m > len) 
2001/0128    
				break; 
		} 
	} else { 
		first = qremove(q); 
2001/0619    
		n = BLEN(first); 
2001/0127    
	} 
 
2001/0128    
	/* copy to user space outside of the ilock */ 
	iunlock(q); 
2001/0203    
	p = s; 
2001/0128    
	for(b = first; b != nil; b = next){ 
2001/0127    
		m = BLEN(b); 
2001/0203    
		if(m > e - p){ 
			m = e - p; 
2001/0128    
			memmove(p, b->rp, m); 
2001/0203    
			p += m; 
2001/0128    
			b->rp += m; 
			break; 
		} 
2001/0127    
		memmove(p, b->rp, m); 
2001/0128    
		p += m; 
		next = b->next; 
		b->next = nil; 
2001/0127    
		freeb(b); 
	} 
2001/0619    
	b = bl2mem(vp, first, len); 
2001/0128    
	ilock(q); 
2001/0127    
 
2001/0128    
	/* take care of any left over partial block */ 
	if(b != nil){ 
2001/0619    
		n -= BLEN(b); 
2001/0128    
		if(q->state & Qmsg) 
			freeb(b); 
		else 
2001/0602/sys/src/9/port/qio.c:1057,10632001/0619/sys/src/9/port/qio.c:1103,1109
2001/0128    
 
	poperror(); 
	qunlock(&q->rlock); 
2001/0203    
	return p-s; 
2001/0619    
	return n; 
1995/0714    
} 
 
1993/0528    
static int 
2001/0602/sys/src/9/port/qio.c:1169,12012001/0619/sys/src/9/port/qio.c:1215,1236
1997/0327    
int 
1995/0714    
qwrite(Queue *q, void *vp, int len) 
{ 
	int n, sofar; 
	Block *b; 
	uchar *p = vp; 
2001/0619    
	Block *b, *next; 
1995/0714    
 
1997/0327    
	QDEBUG if(islo() == 0) 
2001/0619    
	QDEBUG if(!islo()) 
1999/0501    
		print("qwrite hi %lux\n", getcallerpc(&q)); 
1995/0714    
 
	sofar = 0; 
1994/0208    
	do { 
		n = len-sofar; 
1999/0219    
		if(n > Maxatomic) 
			n = Maxatomic; 
1993/0528    
                 
1994/0208    
		b = allocb(n); 
1999/0714    
		setmalloctag(b, (up->text[0]<<24)|(up->text[1]<<16)|(up->text[2]<<8)|up->text[3]); 
1994/0804    
		if(waserror()){ 
			freeb(b); 
			nexterror(); 
		} 
1994/0208    
		memmove(b->wp, p+sofar, n); 
1995/0714    
		poperror(); 
1994/0208    
		b->wp += n; 
1994/0929    
                 
2001/0619    
	b = mem2bl(vp, len); 
	if(waserror()){ 
		freeblist(b); 
		nexterror(); 
	} 
	for(; b != nil; b = next){ 
		next = b->next; 
		b->next = nil; 
1995/0714    
		qbwrite(q, b); 
1994/0929    
                 
1994/0208    
		sofar += n; 
	} while(sofar < len && (q->state & Qmsg) == 0); 
2001/0619    
	} 
	poperror(); 
1993/0528    
 
1993/0526    
	return len; 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)