1 /*
2 * Copyright (c) International Business Machines Corp., 2001-2004
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #include <stdlib.h>
19 #include <assert.h>
20
21 #include "cirlist.h"
22 #include "util.h"
23
init_cirlist(struct cirlist * cl)24 void init_cirlist(struct cirlist *cl)
25 {
26 cl->count = 0;
27 cl->head = NULL;
28 }
29
cl_empty(struct cirlist * cl)30 int cl_empty(struct cirlist *cl)
31 {
32 return !(cl->count);
33 }
34
cl_insert_tail(struct cirlist * cl,cldatatype object)35 void cl_insert_tail(struct cirlist *cl, cldatatype object)
36 {
37 struct cnode *new = ffsb_malloc(sizeof(struct cnode));
38 new->obj = object;
39 if (cl->count == 0) {
40 assert(cl->head == NULL);
41 cl->head = new;
42 cl->head->next = cl->head;
43 cl->head->prev = cl->head;
44 cl->count = 1;
45 } else {
46 if (cl->count == 1) {
47 assert(cl->head->next == cl->head);
48 assert(cl->head->prev == cl->head);
49 cl->head->next = new;
50 cl->head->prev = new;
51 new->next = cl->head;
52 new->prev = cl->head;
53 } else {
54 assert(cl->head->next != cl->head);
55 assert(cl->head->prev != cl->head);
56
57 new->next = cl->head;
58 new->prev = (cl->head)->prev;
59 cl->head->prev->next = new;
60 cl->head->prev = new;
61 }
62 cl->count++;
63 }
64 }
65
cl_remove_head(struct cirlist * cl)66 cldatatype cl_remove_head(struct cirlist *cl)
67 {
68 struct cnode *oldhead = NULL;
69 struct cnode *newhead = NULL;
70 cldatatype ret = NULL;
71
72 if (cl->count == 0) {
73 assert(cl->head == NULL);
74 return NULL;
75 }
76 if (cl->count == 1) {
77 assert(cl->head->next == cl->head);
78 assert(cl->head->prev == cl->head);
79 oldhead = cl->head;
80 cl->head = NULL;
81 cl->count = 0;
82 } else if (cl->count == 2) {
83 oldhead = cl->head;
84 newhead = oldhead->next;
85 newhead->next = newhead;
86 newhead->prev = newhead;
87 cl->head = newhead;
88 cl->count = 1;
89 } else {
90 assert(cl->head->next != cl->head);
91 assert(cl->head->prev != cl->head);
92 oldhead = cl->head;
93 newhead = oldhead->next;
94 newhead->prev = oldhead->prev;
95 newhead->prev->next = newhead;
96 cl->head = newhead;
97 cl->count--;
98 }
99 ret = oldhead->obj;
100 oldhead->obj = (void *)(-1);
101 oldhead->next = (void *)(-1);
102 oldhead->prev = (void *)(-1);
103 free(oldhead);
104
105 return ret;
106 }
107