00001
00002
00003
00004
00005
00006 #ifndef _tredmill_LIST_H
00007 #define _tredmill_LIST_H
00008
00009 #include "tredmill/debug.h"
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 typedef struct tm_list {
00023
00024
00025
00026
00027 struct tm_list *_next;
00028
00029
00030
00031
00032 union {
00033
00034 struct tm_list *_prev;
00035
00036
00037 unsigned long _word;
00038
00039 struct {
00040 #ifdef __LITTLE_ENDIAN
00041 unsigned long _bits : sizeof(void*) * 8 - 2;
00042 unsigned long _color : 2;
00043 #else
00044 unsigned long _color : 2;
00045 unsigned long _bits : sizeof(void*) * 8 - 2;
00046 #endif
00047 } _c;
00048 } _prev;
00049 } tm_list;
00050
00051
00052 /****************************************************************************/
00053
00054
00055
00056 #define tm_list_color(l) (((tm_list*) (l))->_prev._c._color)
00057
00058
00059 #define tm_list_set_color(l,c) (((tm_list*) (l))->_prev._c._color = (c))
00060
00061
00062 #define tm_list_set_next(l,x) (((tm_list*) (l))->_next = (x))
00063
00064
00065 #define tm_list_set_prev(l,x) (((tm_list*) (l))->_prev._c._bits = ((unsigned long) (x) >> 2))
00066
00067
00068 #define tm_list_next(l) ((void*) ((tm_list*) (l))->_next)
00069
00070
00071 #define tm_list_prev(l) ((void*) ((unsigned long) ((tm_list*) (l))->_prev._word & ~ 0x3UL))
00072
00073
00074 #define tm_list_INIT(N) tm_list _##N = { &_##N, { &_##N } }, *N = &_##N;
00075
00076
00077
00078
00079
00080
00081 static __inline
00082 void tm_list_init(void *l)
00083 {
00084 ((tm_list *)l)->_next = l;
00085 ((tm_list *)l)->_prev._prev = l;
00086 }
00087
00088
00089
00090
00091
00092 static __inline
00093 int tm_list_empty(void *l)
00094 {
00095 return tm_list_next(l) == l;
00096 }
00097
00098
00099
00100
00101
00102
00103 static __inline
00104 void * tm_list_first(void *l)
00105 {
00106 return tm_list_empty(l) ?
00107 0 :
00108 tm_list_next(l);
00109 }
00110
00111
00112
00113
00114
00115
00116 static __inline
00117 void * tm_list_last(void *l)
00118 {
00119 return tm_list_empty(l) ?
00120 0 :
00121 tm_list_prev(l);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 static __inline
00131 void tm_list_remove(void *_p)
00132 {
00133 tm_list *p = _p;
00134
00135 tm_list_set_prev((tm_list*) tm_list_next(p), tm_list_prev(p));
00136 tm_list_set_next((tm_list*) tm_list_prev(p), tm_list_next(p));
00137
00138 tm_list_set_next(_p, _p);
00139 tm_list_set_prev(_p, _p);
00140 }
00141
00142
00143
00144
00145
00146 static __inline
00147 void tm_list_insert(void *l, void *p)
00148 {
00149 tm_list_set_next(p, tm_list_next(l));
00150 tm_list_set_prev(p, l);
00151
00152 tm_list_set_prev(tm_list_next(l), p);
00153 tm_list_set_next(l, p);
00154 }
00155
00156
00157
00158
00159
00160 static __inline
00161 void tm_list_append(void *l, void *p)
00162 {
00163 tm_list_insert(tm_list_prev(l), p);
00164 }
00165
00166
00167
00168
00169
00170 static __inline
00171 void tm_list_append_list(void *l, void *p)
00172 {
00173 if ( ! tm_list_empty(p) ) {
00174 tm_list_set_prev(tm_list_next(p), tm_list_prev(l));
00175 tm_list_set_next(tm_list_prev(p), l);
00176 tm_list_set_next(tm_list_prev(l), tm_list_next(p));
00177 tm_list_set_prev(l, tm_list_prev(p));
00178 }
00179
00180 tm_list_init(p);
00181 }
00182
00183
00184
00185
00186
00187 static __inline
00188 void tm_list_remove_and_insert(void *l, void *p)
00189 {
00190 tm_list_remove(p);
00191 tm_list_insert(l, p);
00192 }
00193
00194
00195
00196
00197
00198 static __inline
00199 void tm_list_remove_and_append(void *l, void *p)
00200 {
00201 tm_list_remove(p);
00202 tm_list_append(l, p);
00203 }
00204
00205
00206
00207
00208
00209
00210 static __inline
00211 void * tm_list_take_first(void *_l)
00212 {
00213 tm_list *l = _l;
00214 if ( tm_list_next(l) != l ) {
00215 tm_list *p = tm_list_next(l);
00216 tm_list_remove(p);
00217 return p;
00218 } else {
00219 return 0;
00220 }
00221 }
00222
00223
00224
00225 #define tm_list_LOOP(l, x) do { tm_list *__l = (tm_list*) (l), *__x = tm_list_next(__l); while ( (void *) __x != (void *) (l) ) { x = (void*) __x; __x = tm_list_next(__x); {
00226
00227 #define tm_list_LOOP_END }}} while(0)
00228
00229
00230
00231
00232
00233 static __inline
00234 void tm_list_assert_layout()
00235 {
00236 tm_list_INIT(l);
00237 tm_list_INIT(r);
00238
00239 tm_assert(tm_list_color(l) == 0);
00240
00241 tm_assert_test(sizeof(tm_list*) == sizeof(void*));
00242 tm_assert_test(sizeof(tm_list*) == sizeof(unsigned long));
00243
00244 tm_assert_test(tm_list_next(l) == l);
00245 tm_assert_test(tm_list_prev(l) == l);
00246 tm_assert_test(l->_prev._c._bits == ((unsigned long) (l)) >> 2);
00247 tm_assert_test(tm_list_color(l) == 0);
00248
00249 tm_list_set_color(l, 3);
00250 tm_assert_test(tm_list_next(l) == l);
00251 tm_assert_test(tm_list_prev(l) == l);
00252 tm_assert_test(l->_prev._c._bits == ((unsigned long) (l)) >> 2);
00253 tm_assert_test(tm_list_color(l) == 3);
00254
00255 tm_list_set_color(r, 2);
00256 tm_list_insert(l, r);
00257 tm_assert_test(tm_list_next(l) == (void*) r);
00258 tm_assert_test(tm_list_prev(l) == (void*) r);
00259 tm_assert_test(tm_list_next(r) == (void*) l);
00260 tm_assert_test(tm_list_prev(r) == (void*) l);
00261 tm_assert_test(tm_list_color(l) == 3);
00262 tm_assert_test(tm_list_color(r) == 2);
00263
00264 tm_list_remove(r);
00265 tm_assert_test(tm_list_next(l) == (void*) l);
00266 tm_assert_test(tm_list_prev(l) == (void*) l);
00267 tm_assert_test(tm_list_next(r) == (void*) r);
00268 tm_assert_test(tm_list_prev(r) == (void*) r);
00269 tm_assert_test(tm_list_color(l) == 3);
00270 tm_assert_test(tm_list_color(r) == 2);
00271
00272 tm_list_insert(r, l);
00273 tm_assert_test(tm_list_next(l) == (void*) r);
00274 tm_assert_test(tm_list_prev(l) == (void*) r);
00275 tm_assert_test(tm_list_next(r) == (void*) l);
00276 tm_assert_test(tm_list_prev(r) == (void*) l);
00277 tm_assert_test(tm_list_color(l) == 3);
00278 tm_assert_test(tm_list_color(r) == 2);
00279 }
00280
00281
00282
00283
00284
00285