fifo.c revision 178482
1233294Sstas/*
2102644Snectar * CDDL HEADER START
355682Smarkm *
4142403Snectar * The contents of this file are subject to the terms of the
5233294Sstas * Common Development and Distribution License, Version 1.0 only
6233294Sstas * (the "License").  You may not use this file except in compliance
755682Smarkm * with the License.
855682Smarkm *
955682Smarkm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1055682Smarkm * or http://www.opensolaris.org/os/licensing.
1155682Smarkm * See the License for the specific language governing permissions
1255682Smarkm * and limitations under the License.
1355682Smarkm *
1455682Smarkm * When distributing Covered Code, include this CDDL HEADER in each
1555682Smarkm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1690926Snectar * If applicable, add the following below this CDDL HEADER, with the
1790926Snectar * fields enclosed by brackets "[]" replaced with your own identifying
18233294Sstas * information: Portions Copyright [yyyy] [name of copyright owner]
1990926Snectar *
20233294Sstas * CDDL HEADER END
2190926Snectar */
22233294Sstas/*
2355682Smarkm * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24142403Snectar * Use is subject to license terms.
25142403Snectar */
2655682Smarkm
2755682Smarkm#pragma ident	"%Z%%M%	%I%	%E% SMI"
28233294Sstas
2955682Smarkm/*
30233294Sstas * Routines for manipulating a FIFO queue
31102644Snectar */
32102644Snectar
33102644Snectar#include <stdlib.h>
34127808Snectar
3590926Snectar#include "fifo.h"
36127808Snectar#include "memory.h"
3755682Smarkm
3855682Smarkmtypedef struct fifonode {
3955682Smarkm	void *fn_data;
4055682Smarkm	struct fifonode *fn_next;
4155682Smarkm} fifonode_t;
4255682Smarkm
43178825Sdfrstruct fifo {
4455682Smarkm	fifonode_t *f_head;
45178825Sdfr	fifonode_t *f_tail;
46178825Sdfr};
47178825Sdfr
48142403Snectarfifo_t *
49142403Snectarfifo_new(void)
50233294Sstas{
51233294Sstas	fifo_t *f;
52233294Sstas
53178825Sdfr	f = xcalloc(sizeof (fifo_t));
54178825Sdfr
55178825Sdfr	return (f);
56233294Sstas}
57233294Sstas
58233294Sstas/* Add to the end of the fifo */
59233294Sstasvoid
60233294Sstasfifo_add(fifo_t *f, void *data)
61233294Sstas{
62233294Sstas	fifonode_t *fn = xmalloc(sizeof (fifonode_t));
63233294Sstas
64233294Sstas	fn->fn_data = data;
65233294Sstas	fn->fn_next = NULL;
66233294Sstas
67178825Sdfr	if (f->f_tail == NULL)
68142403Snectar		f->f_head = f->f_tail = fn;
69142403Snectar	else {
70142403Snectar		f->f_tail->fn_next = fn;
71233294Sstas		f->f_tail = fn;
72142403Snectar	}
73142403Snectar}
74142403Snectar
75142403Snectar/* Remove from the front of the fifo */
76142403Snectarvoid *
77142403Snectarfifo_remove(fifo_t *f)
78142403Snectar{
79142403Snectar	fifonode_t *fn;
80142403Snectar	void *data;
81142403Snectar
82142403Snectar	if ((fn = f->f_head) == NULL)
83142403Snectar		return (NULL);
84142403Snectar
85142403Snectar	data = fn->fn_data;
86233294Sstas	if ((f->f_head = fn->fn_next) == NULL)
87142403Snectar		f->f_tail = NULL;
88142403Snectar
89142403Snectar	free(fn);
90142403Snectar
91178825Sdfr	return (data);
92142403Snectar}
93142403Snectar
94142403Snectar/*ARGSUSED*/
95142403Snectarstatic void
96142403Snectarfifo_nullfree(void *arg)
97142403Snectar{
98142403Snectar	/* this function intentionally left blank */
99142403Snectar}
100233294Sstas
101233294Sstas/* Free an entire fifo */
102233294Sstasvoid
103233294Sstasfifo_free(fifo_t *f, void (*freefn)(void *))
104233294Sstas{
105233294Sstas	fifonode_t *fn = f->f_head;
106178825Sdfr	fifonode_t *tmp;
107178825Sdfr
108178825Sdfr	if (freefn == NULL)
109178825Sdfr		freefn = fifo_nullfree;
110178825Sdfr
111178825Sdfr	while (fn) {
112178825Sdfr		(*freefn)(fn->fn_data);
113233294Sstas
114142403Snectar		tmp = fn;
115142403Snectar		fn = fn->fn_next;
116178825Sdfr		free(tmp);
117142403Snectar	}
118142403Snectar
119233294Sstas	free(f);
120178825Sdfr}
121178825Sdfr
122178825Sdfrint
123178825Sdfrfifo_len(fifo_t *f)
124178825Sdfr{
125233294Sstas	fifonode_t *fn;
126233294Sstas	int i;
127233294Sstas
128233294Sstas	for (i = 0, fn = f->f_head; fn; fn = fn->fn_next, i++);
129233294Sstas
130233294Sstas	return (i);
131233294Sstas}
132233294Sstas
133233294Sstasint
134233294Sstasfifo_empty(fifo_t *f)
135233294Sstas{
136233294Sstas	return (f->f_head == NULL);
137233294Sstas}
138233294Sstas
139233294Sstasint
140233294Sstasfifo_iter(fifo_t *f, int (*iter)(void *data, void *arg), void *arg)
141178825Sdfr{
142178825Sdfr	fifonode_t *fn;
143178825Sdfr	int rc;
144178825Sdfr	int ret = 0;
145233294Sstas
146142403Snectar	for (fn = f->f_head; fn; fn = fn->fn_next) {
147233294Sstas		if ((rc = iter(fn->fn_data, arg)) < 0)
148178825Sdfr			return (-1);
149178825Sdfr		ret += rc;
150178825Sdfr	}
151178825Sdfr
152178825Sdfr	return (ret);
153178825Sdfr}
154233294Sstas