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