OpenSS7
SS7 for the
Common Man

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified:

Home Overview Status News Documentation Resources About
   
 Overview
 Status
 News
 Documentation
 Resources
 About

   
Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/bufq.h


File /code/strss7/drivers/bufq.h



#ifndef __BUFQ_H__
#define __BUFQ_H__

#ident "@(#) $RCSfile: bufq.h,v $ $Name:  $($Revision: 0.8.2.6 $) $Date: 2003/04/14 22:07:35 $"

typedef struct bufq {
	lis_spin_lock_t q_lock;
	mblk_t *q_head;
	mblk_t *q_tail;
	size_t q_msgs;
	size_t q_count;
} bufq_t;

static inline void bufq_init(bufq_t * q)
{
	lis_spin_lock_init(&q->q_lock, "bufq-lock");
	q->q_head = NULL;
	q->q_tail = NULL;
	q->q_msgs = 0;
	q->q_count = 0;
}
static inline void bufq_lock(bufq_t * q, int *flags)
{
	lis_spin_lock_irqsave(&q->q_lock, flags);
}
static inline void bufq_unlock(bufq_t * q, int *flags)
{
	lis_spin_unlock_irqrestore(&q->q_lock, flags);
}

static inline size_t bufq_length(bufq_t * q)
{
	return q->q_msgs;
}

static inline size_t bufq_size(bufq_t * q)
{
	return q->q_count;
}

static inline mblk_t *bufq_head(bufq_t * q)
{
	return q->q_head;
}

static inline mblk_t *bufq_tail(bufq_t * q)
{
	return q->q_tail;
}

static inline void __bufq_add(bufq_t * q, mblk_t *mp)
{
	mblk_t *md = mp;
	q->q_msgs++;
	while (md) {
		if (md->b_wptr > md->b_rptr)
			q->q_count += md->b_wptr - md->b_rptr;
		md = md->b_cont;
	}
	assure(q->q_head);
	assure(q->q_tail);
	assure(q->q_msgs != 1 || !q->q_head->b_next);
	assure(q->q_msgs != 1 || !q->q_tail->b_prev);
}

static inline void __bufq_sub(bufq_t * q, mblk_t *mp)
{
	mblk_t *md = mp;
	while (md) {
		if (md->b_wptr > md->b_rptr) {
			if (q->q_count >= md->b_wptr - md->b_rptr)
				q->q_count -= md->b_wptr - md->b_rptr;
			else
				q->q_count = 0;
		}
		md = md->b_cont;
	}
	if (!(--q->q_msgs))
		q->q_count = 0;
	assure(q->q_msgs || !q->q_head);
	assure(q->q_msgs || !q->q_tail);
}

static inline void __bufq_queue(bufq_t * q, mblk_t *mp)
{
	if ((mp->b_prev = q->q_tail))
		mp->b_prev->b_next = mp;
	else
		q->q_head = mp;
	mp->b_next = NULL;
	q->q_tail = mp;
	__bufq_add(q, mp);
}

static inline void bufq_queue(bufq_t * q, mblk_t *mp)
{
	int flags;
	ensure(q && mp, return);
	bufq_lock(q, &flags);
	__bufq_queue(q, mp);
	bufq_unlock(q, &flags);
}

static inline void bufq_queue_head(bufq_t * q, mblk_t *mp)
{
	int flags;
	ensure(q && mp, return);
	bufq_lock(q, &flags);
	if ((mp->b_next = q->q_head))
		mp->b_next->b_prev = mp;
	else
		q->q_tail = mp;
	mp->b_prev = NULL;
	q->q_head = mp;
	__bufq_add(q, mp);
	bufq_unlock(q, &flags);
}

static inline void bufq_insert(bufq_t * q, mblk_t *mp, mblk_t *np)
{
	int flags;
	bufq_lock(q, &flags);
	ensure(q && mp && np, return);
	if ((np->b_prev = mp->b_prev))
		np->b_prev->b_next = np;
	else
		q->q_head = np;
	mp->b_prev = np;
	np->b_next = mp;
	__bufq_add(q, np);
	bufq_unlock(q, &flags);
}

static inline void bufq_append(bufq_t * q, mblk_t *mp, mblk_t *np)
{
	int flags;
	ensure(q && mp && np, return);
	bufq_lock(q, &flags);
	if ((np->b_next = mp->b_next))
		np->b_next->b_prev = np;
	else
		q->q_tail = np;
	mp->b_next = np;
	np->b_prev = mp;
	__bufq_add(q, np);
	bufq_unlock(q, &flags);
}

static inline mblk_t *__bufq_dequeue(bufq_t * q)
{
	mblk_t *mp;
	if ((mp = q->q_head)) {
		if ((q->q_head = mp->b_next))
			mp->b_next->b_prev = NULL;
		else
			q->q_tail = NULL;
		mp->b_next = NULL;
		mp->b_prev = NULL;
		__bufq_sub(q, mp);
	}
	return mp;
}

static inline mblk_t *bufq_dequeue(bufq_t * q)
{
	int flags;
	mblk_t *mp;
	ensure(q, return (NULL));
	bufq_lock(q, &flags);
	mp = __bufq_dequeue(q);
	bufq_unlock(q, &flags);
	return mp;
}

static inline mblk_t *__bufq_dequeue_tail(bufq_t * q)
{
	mblk_t *mp;
	if ((mp = q->q_tail)) {
		if ((q->q_tail = mp->b_prev))
			mp->b_prev->b_next = NULL;
		else
			q->q_head = NULL;
		mp->b_next = NULL;
		mp->b_prev = NULL;
		__bufq_sub(q, mp);
	}
	return (mp);
}

static inline mblk_t *bufq_dequeue_tail(bufq_t * q)
{
	int flags;
	mblk_t *mp;
	ensure(q, return (NULL));
	bufq_lock(q, &flags);
	mp = __bufq_dequeue_tail(q);
	bufq_unlock(q, &flags);
	return mp;
}

static inline mblk_t *__bufq_unlink(bufq_t * q, mblk_t *mp)
{
	ensure(q && mp, return (NULL));
	if (mp->b_next)
		mp->b_next->b_prev = mp->b_prev;
	else
		q->q_tail = mp->b_prev;
	if (mp->b_prev)
		mp->b_prev->b_next = mp->b_next;
	else
		q->q_head = mp->b_next;
	mp->b_next = NULL;
	mp->b_prev = NULL;
	__bufq_sub(q, mp);
	return mp;
}

static inline mblk_t *bufq_unlink(bufq_t * q, mblk_t *mp)
{
	int flags;
	ensure(q && mp, return (NULL));
	bufq_lock(q, &flags);
	__bufq_unlink(q, mp);
	bufq_unlock(q, &flags);
	return (mp);
}

/* splice bufq2 onto the head of bufq1 */
static inline void bufq_splice_head(bufq_t * q1, bufq_t * q2)
{
	mblk_t *mp;
	ensure(q1 && q2, return);
	while ((mp = bufq_dequeue_tail(q2)))
		bufq_queue_head(q1, mp);
	return;
}

/* splice bufq2 onto the tail of bufq1 */
static inline void bufq_splice_tail(bufq_t * q1, bufq_t * q2)
{
	mblk_t *mp;
	ensure(q1 && q2, return);
	while ((mp = bufq_dequeue(q2)))
		bufq_queue(q1, mp);
}

static inline void bufq_freehead(bufq_t * q)
{
	int flags;
	bufq_lock(q, &flags);
	if (q->q_head)
		freemsg(__bufq_dequeue(q));
	bufq_unlock(q, &flags);
}

static inline void bufq_purge(bufq_t * q)
{
	int flags;
	bufq_lock(q, &flags);
	while (q->q_head)
		freemsg(__bufq_dequeue(q));
	bufq_unlock(q, &flags);
}

static inline void __bufq_supply(bufq_t * q, mblk_t *mp)
{
	mblk_t *md = mp;

	while (md) {
		md->b_datap->db_type = M_DATA;
		md->b_rptr = md->b_wptr = md->b_datap->db_base;
		__bufq_queue(q, md);
		md = unlinkb(md);
	}
}

static inline void bufq_supply(bufq_t * q, mblk_t *mp)
{
	int flags;
	bufq_lock(q, &flags);
	__bufq_supply(q, mp);
	bufq_unlock(q, &flags);
}

static inline mblk_t *bufq_resupply(bufq_t * q, mblk_t *mp, int maxsize, int maxcount)
{
	int flags;
	bufq_lock(q, &flags);
	if (bufq_length(q) > maxcount || bufq_size(q) > maxsize) {
		bufq_unlock(q, &flags);
		return mp;
	}
	__bufq_supply(q, mp);
	bufq_unlock(q, &flags);
	return NULL;
}

static inline void freechunks(mblk_t *mp)
{
	mblk_t *dp, *dp_next;
	for (dp = mp; dp; dp_next = dp->b_next, freemsg(dp), dp = dp_next) ;
}

#endif				/* __BUFQ_H__ */


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/bufq.h

OpenSS7
SS7 for the
Common Man
Home Overview Status News Documentation Resources About

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified: