00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _PLIST_H
00034 #define _PLIST_H
00035
00036 #include <stddef.h>
00037
00038 #define PCM_STORE(addr, val) \
00039 *(addr) = val;
00040
00041 #define PCM_BARRIER
00042
00043
00044 struct plist_head {
00045 struct plist_head *next;
00046 struct plist_head *prev;
00047 struct plist_head *next_shadow;
00048 };
00049
00050
00058 static inline void plist_init(struct plist_head *head, struct plist_head *tail)
00059 {
00060 PCM_STORE(&(head->next), tail);
00061 PCM_STORE(&(head->prev), tail);
00062 PCM_STORE(&(tail->next), head);
00063 PCM_STORE(&(tail->prev), head);
00064 PCM_BARRIER
00065 }
00066
00067
00068 static inline void plist_move(struct plist_head *listA, struct plist_head *listB)
00069 {
00070 struct plist_head *listA_next_old = listA->next;
00071 struct plist_head *listA_prev_old = listA->prev;
00072
00073 PCM_STORE(&(listA->prev->next), listA->next);
00074 PCM_BARRIER;
00075 PCM_STORE(&(listA->next), listB);
00076 PCM_BARRIER;
00077 PCM_STORE(&(listB->prev->next), listA);
00078 PCM_BARRIER;
00079 PCM_STORE(&(listA_next_old->prev), listA_prev_old);
00080 PCM_BARRIER;
00081 PCM_STORE(&(listA->prev), listB->prev);
00082 PCM_BARRIER;
00083 PCM_STORE(&(listA->next->prev), listA);
00084 PCM_BARRIER;
00085 }
00086
00094 static inline void plist_recover(struct plist_head *list)
00095 {
00096 struct plist_head *node;
00097 struct plist_head *nodeX;
00098 int count = 0;
00099
00100 for (node = list; prefetch(node->next), node != list || count == 0;
00101 node = node->next, count++)
00102 {
00103 if (node->next == node && node->prev == node) {
00104
00105 return;
00106 }
00107 recover:
00108 if (node->next->prev->prev == node ) {
00109 nodeX = node->next->prev;
00110 if (nodeX->next->prev != NULL &&
00111 nodeX->next->prev->next == nodeX ) {
00112 PCM_STORE(&(nodeX->prev->next->prev), nodeX->prev);
00113 PCM_BARRIER
00114 goto recover;
00115 } else {
00116 PCM_STORE(&(nodeX->next), node->next);
00117 PCM_BARRIER;
00118 PCM_STORE(&(node->next), nodeX);
00119 PCM_BARRIER;
00120 goto recover;
00121 }
00122 } else if (node->next->next->prev == node ) {
00123 nodeX = node->next;
00124 if (nodeX->prev != NULL &&
00125 nodeX->prev->next->prev == nodeX ) {
00126 PCM_STORE(&(node->next), node->next->next);
00127 PCM_BARRIER;
00128 goto recover;
00129 } else {
00130 PCM_STORE(&(nodeX->prev), node);
00131 PCM_BARRIER;
00132 PCM_STORE(&(nodeX->next->prev), nodeX);
00133 PCM_BARRIER;
00134 goto recover;
00135 }
00136 }
00137 }
00138 }
00139
00140 static inline void plist_init_S(struct plist_head *head, struct plist_head *tail)
00141 {
00142 PCM_STORE(&(head->next), tail);
00143 PCM_BARRIER
00144 }
00145
00152 static inline void plist_add_S(struct plist_head *node, struct plist_head *head)
00153 {
00154
00155 PCM_STORE(&(node->next), head->next);
00156 PCM_STORE(&(head->next), node);
00157 PCM_BARRIER
00158
00159 }
00160
00164 static inline void plist_move_DtoS(struct plist_head *listA, struct plist_head *listB)
00165 {
00166 struct plist_head *listA_next_old = listA->next;
00167 struct plist_head *listA_prev_old = listA->prev;
00168
00169 PCM_STORE(&(listA->prev->next), listA->next);
00170 PCM_BARRIER;
00171 PCM_STORE(&(listA->next), listB);
00172 PCM_BARRIER;
00173 PCM_STORE(&(listB->prev->next), listA);
00174 PCM_BARRIER;
00175 PCM_STORE(&(listA_next_old->prev), listA_prev_old);
00176 PCM_BARRIER;
00177 PCM_STORE(&(listA->prev), NULL);
00178 PCM_BARRIER;
00179 }
00180
00181
00185 static inline void plist_move_StoD(struct plist_head *listA, struct plist_head *listB)
00186 {
00187 struct plist_head *listA_next_old = listA->next;
00188 struct plist_head *listA_prev_old = listA->prev;
00189
00190 PCM_STORE(&(listA->prev->next), listA->next);
00191 PCM_BARRIER;
00192 PCM_STORE(&(listA->next), listB);
00193 PCM_BARRIER;
00194 PCM_STORE(&(listB->prev->next), listA);
00195 PCM_BARRIER;
00196 PCM_STORE(&(listA_next_old->prev), listA_prev_old);
00197 PCM_BARRIER;
00198 PCM_STORE(&(listA->prev), listB->prev);
00199 PCM_BARRIER;
00200 PCM_STORE(&(listA->next->prev), listA);
00201 PCM_BARRIER;
00202 }
00203
00204
00205
00206 #endif