The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
list.h
Go to the documentation of this file.
1 
31 #pragma once
32 
33 #include <stddef.h>
34 #include <string.h>
35 #include <assert.h>
36 
37 #include <arch/atomic.h>
38 
40 typedef struct rootsim_list {
41  size_t size;
42  void *head; // Generic pointers: nodes of the list must have a next/prev pointer properly typed
43  void *tail;
44 // atomic_t counter;
45 } rootsim_list;
46 
48 #define my_offsetof(st, m) ((size_t)( (unsigned char *)&((st)->m ) - (unsigned char *)(st)))
49 
51 #define list(type) type *
52 
59 #define new_list(type) (type *)({ \
60  void *__lmptr; \
61  __lmptr = (void *)rsalloc(sizeof(struct rootsim_list)); \
62  bzero(__lmptr, sizeof(struct rootsim_list));\
63  __lmptr;\
64  })
65 
66 // Get the size of the current list.
67 #define list_sizeof(list) ((struct rootsim_list *)list)->size
68 
74 #define list_head(list) ((__typeof__ (list))(((rootsim_list *)(list))->head))
75 
81 #define list_tail(list) ((__typeof__ (list))(((rootsim_list *)(list))->tail))
82 
88 #define list_next(ptr) ((ptr)->next)
89 
95 #define list_prev(ptr) ((ptr)->prev)
96 
98 #define get_key(data) ({\
99  char *__key_ptr = ((char *)(data) + __key_position);\
100  double *__key_double_ptr = (double *)__key_ptr;\
101  *__key_double_ptr;\
102  })
103 
110 #define list_empty(list) (((rootsim_list *)list)->size == 0)
111 
112 #define list_insert_tail(li, data) \
113  do { \
114  __typeof__(data) __new_n = (data); /* in-block scope variable */\
115  size_t __size_before;\
116  rootsim_list *__l;\
117  __new_n->next = NULL;\
118  __new_n->prev = NULL;\
119  do {\
120  __l = (rootsim_list *)(li);\
121  assert(__l);\
122  __size_before = __l->size;\
123  if(__l->size == 0) { /* is the list empty? */\
124  __l->head = __new_n;\
125  __l->tail = __new_n;\
126  break; /* leave the inner do-while */\
127  }\
128  __new_n->next = NULL; /* Otherwise add at the end */\
129  __new_n->prev = __l->tail;\
130  ((__typeof__(data))(__l->tail))->next = __new_n;\
131  __l->tail = __new_n;\
132  } while(0);\
133  __l->size++;\
134  assert(__l->size == (__size_before + 1));\
135  } while(0)
136 
137 #define list_insert_head(li, data) \
138  do { \
139  __typeof__(data) __new_n = (data); /* in-block scope variable */\
140  size_t __size_before;\
141  rootsim_list *__l;\
142  __new_n->next = NULL;\
143  __new_n->prev = NULL;\
144  do {\
145  __l = (rootsim_list *)(li);\
146  assert(__l);\
147  __size_before = __l->size;\
148  if(__l->size == 0) { /* is the list empty? */\
149  __l->head = __new_n;\
150  __l->tail = __new_n;\
151  break; /* leave the inner do-while */\
152  }\
153  __new_n->prev = NULL; /* Otherwise add at the beginning */\
154  __new_n->next = __l->head;\
155  ((__typeof(data))__l->head)->prev = __new_n;\
156  __l->head = __new_n;\
157  } while(0);\
158  __l->size++;\
159  assert(__l->size == (__size_before + 1));\
160  } while(0)
161 
163 #define list_insert(li, key_name, data)\
164  do {\
165  __typeof__(data) __n; /* in-block scope variable */\
166  __typeof__(data) __new_n = (data);\
167  size_t __key_position = my_offsetof((li), key_name);\
168  double __key;\
169  size_t __size_before;\
170  rootsim_list *__l;\
171  do {\
172  __l = (rootsim_list *)(li);\
173  assert(__l);\
174  __size_before = __l->size;\
175  if(__l->size == 0) { /* Is the list empty? */\
176  __new_n->prev = NULL;\
177  __new_n->next = NULL;\
178  __l->head = __new_n;\
179  __l->tail = __new_n;\
180  break;\
181  }\
182  __key = get_key(__new_n); /* Retrieve the new node's key */\
183  /* Scan from the tail, as keys are ordered in an increasing order */\
184  __n = __l->tail;\
185  while(__n != NULL && __key < get_key(__n)) {\
186  __n = __n->prev;\
187  }\
188  /* Insert depending on the position */\
189  if(__n == __l->tail) { /* tail */\
190  __new_n->next = NULL;\
191  ((__typeof(data))__l->tail)->next = __new_n;\
192  __new_n->prev = __l->tail;\
193  __l->tail = __new_n;\
194  } else if(__n == NULL) { /* head */\
195  __new_n->prev = NULL;\
196  __new_n->next = __l->head;\
197  ((__typeof(data))__l->head)->prev = __new_n;\
198  __l->head = __new_n;\
199  } else { /* middle */\
200  __new_n->prev = __n;\
201  __new_n->next = __n->next;\
202  __n->next->prev = __new_n;\
203  __n->next = __new_n;\
204  }\
205  } while(0);\
206  __l->size++;\
207  assert(__l->size == (__size_before + 1));\
208  } while(0)
209 
210 #define list_delete_by_content(li, node)\
211  do {\
212  __typeof__(node) __n = (node); /* in-block scope variable */\
213  rootsim_list *__l;\
214  size_t __size_before;\
215  __l = (rootsim_list *)(li);\
216  assert(__l);\
217  __size_before = __l->size;\
218  /* Unchain the node */\
219  if(__l->head == __n) {\
220  __l->head = __n->next;\
221  if(__l->head != NULL) {\
222  ((__typeof(node))__l->head)->prev = NULL;\
223  }\
224  }\
225  if(__l->tail == __n) {\
226  __l->tail = __n->prev;\
227  if(__l->tail != NULL) {\
228  ((__typeof(node))__l->tail)->next = NULL;\
229  }\
230  }\
231  if(__n->next != NULL) {\
232  __n->next->prev = __n->prev;\
233  }\
234  if(__n->prev != NULL) {\
235  __n->prev->next = __n->next;\
236  }\
237  __n->next = (void *)0xBEEFC0DE;\
238  __n->prev = (void *)0xDEADC0DE;\
239  __l->size--;\
240  assert(__l->size == (__size_before - 1));\
241  } while(0)
242 
243 #define list_pop(list)\
244  do {\
245  rootsim_list *__l;\
246  size_t __size_before;\
247  __typeof__ (list) __n;\
248  __typeof__ (list) __n_next;\
249  __l = (rootsim_list *)(list);\
250  assert(__l);\
251  __size_before = __l->size;\
252  __n = __l->head;\
253  if(__n != NULL) {\
254  __l->head = __n->next;\
255  if(__n->next != NULL) {\
256  __n->next->prev = NULL;\
257  }\
258  __n_next = __n->next;\
259  __n->next = (void *)0xDEFEC8ED;\
260  __n->prev = (void *)0xDEFEC8ED;\
261  __n = __n_next;\
262  __l->size--;\
263  assert(__l->size == (__size_before - 1));\
264  }\
265  } while(0)
266 
268 #define list_trunc(list, key_name, key_value, release_fn) \
269  ({\
270  rootsim_list *__l = (rootsim_list *)(list);\
271  __typeof__(list) __n;\
272  __typeof__(list) __n_adjacent;\
273  unsigned int __deleted = 0;\
274  size_t __key_position = my_offsetof((list), key_name);\
275  assert(__l);\
276  size_t __size_before = __l->size;\
277  /* Attempting to truncate an empty list? */\
278  if(__l->size > 0) {\
279  __n = __l->head;\
280  while(__n != NULL && get_key(__n) < (key_value)) {\
281  __deleted++;\
282  __n_adjacent = __n->next;\
283  __n->next = (void *)0xBAADF00D;\
284  __n->prev = (void *)0xBAADF00D;\
285  release_fn(__n);\
286  __n = __n_adjacent;\
287  }\
288  __l->head = __n;\
289  if(__l->head != NULL)\
290  ((__typeof__(list))__l->head)->prev = NULL;\
291  }\
292  __l->size -= __deleted;\
293  assert(__l->size == (__size_before - __deleted));\
294  __deleted;\
295  })
296 
297 #define list_size(list) ((rootsim_list *)(list))->size
struct rootsim_list rootsim_list
This structure defines a generic list.
Atomic operations.
This structure defines a generic list.
Definition: list.h:40