Subject: Re: Rewrite of buffer queue interface
To: Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
From: Chris Jepeway <jepeway@blasted-heath.com>
List: tech-kern
Date: 09/04/2002 21:16:27
>`BUFQ_PUT' puts a buffer into the queue.
>
>`BUFQ_GET' gets (and removes) the next buffer from the queue.
>
>`BUFQ_PEEK' gets (without removal) the next buffer from the queue.
Does MP-safety matter, here?  If so, I'm not sure the BUFQ_PEEK()
operation can be made MP-safe.

Eg, I don't think code like this

	bp = BUFQ_PEEK(bstate);
	if (I like bp) {
		/* Dequeue bp so nobody else gets it */
		(void) BUFQ_GET(bstate);

		/* Do whatever I want with bp */
	}

works in the MP case.  I think you're stuck doing

	bp = BUFQ_GET(bstate);
	if (I don't like bp)
		BUFQ_PUT(bstate, bp);
	else {
		/*
		 * I know I like bp, and it's safe
		 * for me to do with it as I wish
		 */

	}

And something like

    retry:
	bp = BUFQ_PEEK(bstate);
	if (I like bp) {
		/* Dequeue bp */
		if ((fbp = BUFQ_GET(bstate)) != bp)
			/*
			 * Failed to get it; somebody else
			 * must have either beaten us to it
			 * or added a buf while we were peeking
			 */
			BUFQ_PUT(bstate, fbp);
			goto retry;

		/*
		 * I've got the buffer I know I like
		 * and I know nobody else can get it
		 */
	}

seems...clunky and dangerous.  Certainly, it can lead to starvation-like
trouble if the queue grows from the front while you're peeking.  You could
handle that trouble with a BUFQ_REMOVE() operation, as in

    retry:
	bp = BUFQ_PEEK(bstate);
	if (I like bp) {
		/* Dequeue bp so nobody else gets it */
		if (!BUFQ_REMOVE(bstate, bp))
			/*
			 * Failed to get it; somebody else
			 * must have either beaten us to it
			 * or added a buf while we were peeking
			 */
			goto retry;

		 /*
		  * Do as I wish with bp
		  */
	}

but that still seems clunky to me.

And it's still dangerous, since I'm not sure you can dereference
bp in the "I like bp" test, above, until you're sure nobody else
uses it.

So, really, I'm asking whether you can use the result you get from
BUFQ_PEEK() in any useful way when another processor might be
manipulating the queue.

Well, firstly, whether MP is a concern, then whether BUFQ_PEEK()
can be MP useful.

>Juergen Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)
Chris <jepeway@blasted-heath.com>.