X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/1b8b7ec966d302f6a49ec6fc84c5afca7901dfcd..0e6d2fea3ba3887101358f2ef4f24192a40de603:/src/xbt/fifo.c diff --git a/src/xbt/fifo.c b/src/xbt/fifo.c index 3ea147bfaf..bf3e61e6fe 100644 --- a/src/xbt/fifo.c +++ b/src/xbt/fifo.c @@ -7,9 +7,17 @@ #include "xbt/sysdep.h" #include "xbt/log.h" +#include "xbt/mallocator.h" #include "fifo_private.h" +#include "xbt_modinter.h" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(fifo,xbt,"FIFO"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_fifo,xbt,"FIFO"); + +static void* fifo_item_mallocator_new_f(void); +static void fifo_item_mallocator_free_f(void* item); +static void fifo_item_mallocator_reset_f(void* item); + +static xbt_mallocator_t item_mallocator = NULL; /** Constructor * \return a new fifo @@ -18,6 +26,13 @@ xbt_fifo_t xbt_fifo_new(void) { xbt_fifo_t fifo; fifo = xbt_new0(struct xbt_fifo,1); + + if (item_mallocator == NULL) { + item_mallocator = xbt_mallocator_new(256, + fifo_item_mallocator_new_f, + fifo_item_mallocator_free_f, + fifo_item_mallocator_reset_f); + } return fifo; } @@ -32,11 +47,11 @@ void xbt_fifo_free(xbt_fifo_t l) for (b = xbt_fifo_get_first_item(l); b; tmp = b, b = b->next, xbt_fifo_free_item(tmp)); - free(l); + xbt_free(l); return; } -/* Push +/** Push * \param l list * \param t element * \return the bucket that was just added @@ -119,6 +134,7 @@ void *xbt_fifo_shift(xbt_fifo_t l) */ void xbt_fifo_push_item(xbt_fifo_t l, xbt_fifo_item_t new) { + xbt_assert0((new->next == NULL)&&(new->prev == NULL),"Invalid item!"); (l->count)++; if (l->head == NULL) { l->head = new; @@ -144,7 +160,7 @@ xbt_fifo_item_t xbt_fifo_pop_item(xbt_fifo_t l) return NULL; item = l->tail; - + l->tail = item->prev; if (l->tail == NULL) l->head = NULL; @@ -152,6 +168,9 @@ xbt_fifo_item_t xbt_fifo_pop_item(xbt_fifo_t l) l->tail->next = NULL; (l->count)--; + + item->prev = NULL; + return item; } @@ -163,6 +182,7 @@ xbt_fifo_item_t xbt_fifo_pop_item(xbt_fifo_t l) */ void xbt_fifo_unshift_item(xbt_fifo_t l, xbt_fifo_item_t new) { + xbt_assert0((new->next == NULL)&&(new->prev == NULL),"Invalid item!"); (l->count)++; if (l->head == NULL) { l->head = new; @@ -197,6 +217,9 @@ xbt_fifo_item_t xbt_fifo_shift_item(xbt_fifo_t l) l->head->prev = NULL; (l->count)--; + + item->next = NULL; + return item; } @@ -206,8 +229,9 @@ xbt_fifo_item_t xbt_fifo_shift_item(xbt_fifo_t l) * * removes the first occurence of \a t from \a l. * \warning it will not remove duplicates + * \return 1 if an item was removed and 0 otherwise. */ -void xbt_fifo_remove(xbt_fifo_t l, void *t) +int xbt_fifo_remove(xbt_fifo_t l, void *t) { xbt_fifo_item_t current, current_next; @@ -220,37 +244,66 @@ void xbt_fifo_remove(xbt_fifo_t l, void *t) xbt_fifo_remove_item(l, current); xbt_fifo_free_item(current); /* WILL NOT REMOVE DUPLICATES */ - break; + return 1; } - return; + return 0; +} + + +/** + * \param l + * \param t an objet + * + * removes all occurences of \a t from \a l. + * \return 1 if an item was removed and 0 otherwise. + */ +int xbt_fifo_remove_all(xbt_fifo_t l, void *t) +{ + xbt_fifo_item_t current, current_next; + int res=0; + + for (current = l->head; current; current = current_next) { + current_next = current->next; + if (current->content != t) + continue; + /* remove the item */ + xbt_fifo_remove_item(l, current); + xbt_fifo_free_item(current); + res=1; + } + return res; } /** * \param l a list * \param current a bucket * - * removes a the bucket \a current from the list \a l + * removes a bucket \a current from the list \a l. This function implicitely + * assumes (and doesn't check!) that this item belongs to this list... */ void xbt_fifo_remove_item(xbt_fifo_t l, xbt_fifo_item_t current) { if (l->head == l->tail) { /* special case */ - l->head = NULL; - l->tail = NULL; - (l->count)--; - return; - } - - if (current == l->head) { /* It's the head */ - l->head = current->next; - l->head->prev = NULL; - } else if (current == l->tail) { /* It's the tail */ - l->tail = current->prev; - l->tail->next = NULL; - } else { /* It's in the middle */ - current->prev->next = current->next; - current->next->prev = current->prev; - } + xbt_assert0((current==l->head),"This item is not in the list!"); + l->head = NULL; + l->tail = NULL; (l->count)--; + current->prev = current->next = NULL; + return; + } + + if (current == l->head) { /* It's the head */ + l->head = current->next; + l->head->prev = NULL; + } else if (current == l->tail) { /* It's the tail */ + l->tail = current->prev; + l->tail->next = NULL; + } else { /* It's in the middle */ + current->prev->next = current->next; + current->next->prev = current->prev; + } + (l->count)--; + current->prev = current->next = NULL; } /** @@ -307,12 +360,26 @@ xbt_fifo_t xbt_fifo_copy(xbt_fifo_t f) return copy; } +/* Functions passed to the mallocator constructor */ +static void* fifo_item_mallocator_new_f(void) { + return xbt_new(s_xbt_fifo_item_t, 1); +} + +static void fifo_item_mallocator_free_f(void* item) { + xbt_free(item); +} + +static void fifo_item_mallocator_reset_f(void* item) { + /* memset to zero like calloc */ + memset(item, 0, sizeof(s_xbt_fifo_item_t)); +} + /** Constructor * \return a new bucket */ xbt_fifo_item_t xbt_fifo_new_item(void) { - return xbt_new0(struct xbt_fifo_item,1); + return xbt_mallocator_get(item_mallocator); } /** \deprecated Use #xbt_fifo_new_item instead. @@ -350,7 +417,7 @@ void *xbt_fifo_get_item_content(xbt_fifo_item_t i) */ void xbt_fifo_free_item(xbt_fifo_item_t b) { - free(b); + xbt_mallocator_release(item_mallocator, b); return; } @@ -360,7 +427,7 @@ void xbt_fifo_free_item(xbt_fifo_item_t b) void xbt_fifo_freeitem(xbt_fifo_item_t b) { WARN0("This function is deprecated. Use xbt_fifo_free_item."); - free(b); + xbt_fifo_free_item(b); return; } @@ -426,6 +493,16 @@ xbt_fifo_item_t xbt_fifo_getPrevItem(xbt_fifo_item_t i) return xbt_fifo_get_prev_item(i); } +/** + * Destroy the fifo item mallocator. + * This is an internal XBT function called by xbt_exit(). + */ +void xbt_fifo_exit(void) { + if (item_mallocator != NULL) { + xbt_mallocator_free(item_mallocator); + } +} + /* @} */