os161-1.99
 All Data Structures
threadlist.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * Thread list functions, rather dull.
00032  */
00033 
00034 #include <types.h>
00035 #include <lib.h>
00036 #include <thread.h>
00037 #include <threadlist.h>
00038 
00039 void
00040 threadlistnode_init(struct threadlistnode *tln, struct thread *t)
00041 {
00042         DEBUGASSERT(tln != NULL);
00043         KASSERT(t != NULL);
00044 
00045         tln->tln_next = NULL;
00046         tln->tln_prev = NULL;
00047         tln->tln_self = t;
00048 }
00049 
00050 void
00051 threadlistnode_cleanup(struct threadlistnode *tln)
00052 {
00053         DEBUGASSERT(tln != NULL);
00054 
00055         KASSERT(tln->tln_next == NULL);
00056         KASSERT(tln->tln_prev == NULL);
00057         KASSERT(tln->tln_self != NULL);
00058 }
00059 
00060 void
00061 threadlist_init(struct threadlist *tl)
00062 {
00063         DEBUGASSERT(tl != NULL);
00064 
00065         tl->tl_head.tln_next = &tl->tl_tail;
00066         tl->tl_head.tln_prev = NULL;
00067         tl->tl_tail.tln_next = NULL;
00068         tl->tl_tail.tln_prev = &tl->tl_head;
00069         tl->tl_head.tln_self = NULL;
00070         tl->tl_tail.tln_self = NULL;
00071         tl->tl_count = 0;
00072 }
00073 
00074 void
00075 threadlist_cleanup(struct threadlist *tl)
00076 {
00077         DEBUGASSERT(tl != NULL);
00078         DEBUGASSERT(tl->tl_head.tln_next == &tl->tl_tail);
00079         DEBUGASSERT(tl->tl_head.tln_prev == NULL);
00080         DEBUGASSERT(tl->tl_tail.tln_next == NULL);
00081         DEBUGASSERT(tl->tl_tail.tln_prev == &tl->tl_head);
00082         DEBUGASSERT(tl->tl_head.tln_self == NULL);
00083         DEBUGASSERT(tl->tl_tail.tln_self == NULL);
00084 
00085         KASSERT(threadlist_isempty(tl));
00086         KASSERT(tl->tl_count == 0);
00087 
00088         /* nothing (else) to do */
00089 }
00090 
00091 bool
00092 threadlist_isempty(struct threadlist *tl)
00093 {
00094         DEBUGASSERT(tl != NULL);
00095 
00096         return (tl->tl_count == 0);
00097 }
00098 
00099 ////////////////////////////////////////////////////////////
00100 // internal
00101 
00102 /*
00103  * Do insertion. Doesn't update tl_count.
00104  */
00105 static
00106 void
00107 threadlist_insertafternode(struct threadlistnode *onlist, struct thread *t)
00108 {
00109         struct threadlistnode *addee;
00110 
00111         addee = &t->t_listnode;
00112 
00113         DEBUGASSERT(addee->tln_prev == NULL);
00114         DEBUGASSERT(addee->tln_next == NULL);
00115 
00116         addee->tln_prev = onlist;
00117         addee->tln_next = onlist->tln_next;
00118         addee->tln_prev->tln_next = addee;
00119         addee->tln_next->tln_prev = addee;
00120 }
00121 
00122 /*
00123  * Do insertion. Doesn't update tl_count.
00124  */
00125 static
00126 void
00127 threadlist_insertbeforenode(struct thread *t, struct threadlistnode *onlist)
00128 {
00129         struct threadlistnode *addee;
00130 
00131         addee = &t->t_listnode;
00132 
00133         DEBUGASSERT(addee->tln_prev == NULL);
00134         DEBUGASSERT(addee->tln_next == NULL);
00135 
00136         addee->tln_prev = onlist->tln_prev;
00137         addee->tln_next = onlist;
00138         addee->tln_prev->tln_next = addee;
00139         addee->tln_next->tln_prev = addee;
00140 }
00141 
00142 /*
00143  * Do removal. Doesn't update tl_count.
00144  */
00145 static
00146 void
00147 threadlist_removenode(struct threadlistnode *tln)
00148 {
00149         DEBUGASSERT(tln != NULL);
00150         DEBUGASSERT(tln->tln_prev != NULL);
00151         DEBUGASSERT(tln->tln_next != NULL);
00152 
00153         tln->tln_prev->tln_next = tln->tln_next;
00154         tln->tln_next->tln_prev = tln->tln_prev;
00155         tln->tln_prev = NULL;
00156         tln->tln_next = NULL;
00157 }
00158 
00159 ////////////////////////////////////////////////////////////
00160 // public
00161 
00162 void
00163 threadlist_addhead(struct threadlist *tl, struct thread *t)
00164 {
00165         DEBUGASSERT(tl != NULL);
00166         DEBUGASSERT(t != NULL);
00167 
00168         threadlist_insertafternode(&tl->tl_head, t);
00169         tl->tl_count++;
00170 }
00171 
00172 void
00173 threadlist_addtail(struct threadlist *tl, struct thread *t)
00174 {
00175         DEBUGASSERT(tl != NULL);
00176         DEBUGASSERT(t != NULL);
00177 
00178         threadlist_insertbeforenode(t, &tl->tl_tail);
00179         tl->tl_count++;
00180 }
00181 
00182 struct thread *
00183 threadlist_remhead(struct threadlist *tl)
00184 {
00185         struct threadlistnode *tln;
00186 
00187         DEBUGASSERT(tl != NULL);
00188 
00189         tln = tl->tl_head.tln_next;
00190         if (tln->tln_next == NULL) {
00191                 /* list was empty  */
00192                 return NULL;
00193         }
00194         threadlist_removenode(tln);
00195         DEBUGASSERT(tl->tl_count > 0);
00196         tl->tl_count--;
00197         return tln->tln_self;
00198 }
00199 
00200 struct thread *
00201 threadlist_remtail(struct threadlist *tl)
00202 {
00203         struct threadlistnode *tln;
00204 
00205         DEBUGASSERT(tl != NULL);
00206 
00207         tln = tl->tl_tail.tln_prev;
00208         if (tln->tln_prev == NULL) {
00209                 /* list was empty  */
00210                 return NULL;
00211         }
00212         threadlist_removenode(tln);
00213         DEBUGASSERT(tl->tl_count > 0);
00214         tl->tl_count--;
00215         return tln->tln_self;
00216 }
00217 
00218 void
00219 threadlist_insertafter(struct threadlist *tl,
00220                        struct thread *onlist, struct thread *addee)
00221 {
00222         threadlist_insertafternode(&onlist->t_listnode, addee);
00223         tl->tl_count++;
00224 }
00225 
00226 void
00227 threadlist_insertbefore(struct threadlist *tl,
00228                         struct thread *addee, struct thread *onlist)
00229 {
00230         threadlist_insertbeforenode(addee, &onlist->t_listnode);
00231         tl->tl_count++;
00232 }
00233 
00234 void
00235 threadlist_remove(struct threadlist *tl, struct thread *t)
00236 {
00237         threadlist_removenode(&t->t_listnode);
00238         DEBUGASSERT(tl->tl_count > 0);
00239         tl->tl_count--;
00240 }
 All Data Structures