X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2f810149832a2d855c33d0df5b02d736c2081e41..9698647b08a3a2771bd8217f9698b014af69a346:/src/xbt/fifo.c diff --git a/src/xbt/fifo.c b/src/xbt/fifo.c index 57e0912f26..55a6ab02fd 100644 --- a/src/xbt/fifo.c +++ b/src/xbt/fifo.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team. +/* Copyright (c) 2004-2014. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -8,7 +8,7 @@ #include "xbt/log.h" #include "xbt/mallocator.h" #include "fifo_private.h" -#include "xbt_modinter.h" +#include "src/xbt_modinter.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_fifo, xbt, "FIFO"); @@ -23,13 +23,11 @@ static xbt_mallocator_t item_mallocator = NULL; */ xbt_fifo_t xbt_fifo_new(void) { - xbt_fifo_t fifo; - fifo = xbt_new0(struct xbt_fifo, 1); + xbt_fifo_t fifo = xbt_new0(struct xbt_fifo, 1); return fifo; } - /** Destructor * \param l poor victim * @@ -49,11 +47,15 @@ void xbt_fifo_free(xbt_fifo_t l) */ void xbt_fifo_reset(xbt_fifo_t l) { - xbt_fifo_item_t b, tmp; + xbt_fifo_item_t b = xbt_fifo_get_first_item(l); - for (b = xbt_fifo_get_first_item(l); b; - tmp = b, b = b->next, xbt_fifo_free_item(tmp)); - l->head = l->tail = NULL; + while (b) { + xbt_fifo_item_t tmp = b; + b = b->next; + xbt_fifo_free_item(tmp); + } + l->head = NULL; + l->tail = NULL; } /** Push @@ -65,9 +67,7 @@ void xbt_fifo_reset(xbt_fifo_t l) */ xbt_fifo_item_t xbt_fifo_push(xbt_fifo_t l, void *t) { - xbt_fifo_item_t new; - - new = xbt_fifo_new_item(); + xbt_fifo_item_t new = xbt_fifo_new_item(); new->content = t; xbt_fifo_push_item(l, new); @@ -83,15 +83,13 @@ xbt_fifo_item_t xbt_fifo_push(xbt_fifo_t l, void *t) */ void *xbt_fifo_pop(xbt_fifo_t l) { - xbt_fifo_item_t item; - void *content; - if (l == NULL) return NULL; - if (!(item = xbt_fifo_pop_item(l))) + xbt_fifo_item_t item = xbt_fifo_pop_item(l); + if (!item) return NULL; - content = item->content; + void *content = item->content; xbt_fifo_free_item(item); return content; } @@ -105,9 +103,7 @@ void *xbt_fifo_pop(xbt_fifo_t l) */ xbt_fifo_item_t xbt_fifo_unshift(xbt_fifo_t l, void *t) { - xbt_fifo_item_t new; - - new = xbt_fifo_new_item(); + xbt_fifo_item_t new = xbt_fifo_new_item(); new->content = t; xbt_fifo_unshift_item(l, new); return new; @@ -122,15 +118,13 @@ xbt_fifo_item_t xbt_fifo_unshift(xbt_fifo_t l, void *t) */ void *xbt_fifo_shift(xbt_fifo_t l) { - xbt_fifo_item_t item; - void *content; - if (l == NULL) return NULL; - if (!(item = xbt_fifo_shift_item(l))) + xbt_fifo_item_t item = xbt_fifo_shift_item(l); + if (!item) return NULL; - content = item->content; + void *content = item->content; xbt_fifo_free_item(item); return content; } @@ -163,12 +157,10 @@ void xbt_fifo_push_item(xbt_fifo_t l, xbt_fifo_item_t new) */ xbt_fifo_item_t xbt_fifo_pop_item(xbt_fifo_t l) { - xbt_fifo_item_t item; - if (l->tail == NULL) return NULL; - item = l->tail; + xbt_fifo_item_t item = l->tail; l->tail = item->prev; if (l->tail == NULL) @@ -201,7 +193,6 @@ void xbt_fifo_unshift_item(xbt_fifo_t l, xbt_fifo_item_t new) new->next = l->head; new->next->prev = new; l->head = new; - return; } /** Shift bucket @@ -212,12 +203,10 @@ void xbt_fifo_unshift_item(xbt_fifo_t l, xbt_fifo_item_t new) */ xbt_fifo_item_t xbt_fifo_shift_item(xbt_fifo_t l) { - xbt_fifo_item_t item; - if (l->head == NULL) return NULL; - item = l->head; + xbt_fifo_item_t item = l->head; l->head = item->next; if (l->head == NULL) @@ -236,49 +225,49 @@ xbt_fifo_item_t xbt_fifo_shift_item(xbt_fifo_t l) * \param l * \param t an objet * - * removes the first occurence of \a t from \a l. + * removes the first occurrence of \a t from \a l. * \warning it will not remove duplicates * \return 1 if an item was removed and 0 otherwise. */ int xbt_fifo_remove(xbt_fifo_t l, void *t) { - xbt_fifo_item_t current, current_next; - + xbt_fifo_item_t current; + xbt_fifo_item_t current_next; 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); - /* WILL NOT REMOVE DUPLICATES */ - return 1; + if (current->content == t) { + /* remove the item */ + xbt_fifo_remove_item(l, current); + xbt_fifo_free_item(current); + /* WILL NOT REMOVE DUPLICATES */ + return 1; + } } return 0; } - /** * \param l * \param t an objet * - * removes all occurences of \a t from \a l. + * removes all occurrences 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; + xbt_fifo_item_t current; + xbt_fifo_item_t 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; + if (current->content == t){ + /* remove the item */ + xbt_fifo_remove_item(l, current); + xbt_fifo_free_item(current); + res = 1; + } } return res; } @@ -287,7 +276,7 @@ int xbt_fifo_remove_all(xbt_fifo_t l, void *t) * \param l a list * \param current a bucket * - * removes a bucket \a current from the list \a l. This function implicitely + * removes a bucket \a current from the list \a l. This function implicitly * 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) @@ -297,7 +286,8 @@ void xbt_fifo_remove_item(xbt_fifo_t l, xbt_fifo_item_t current) l->head = NULL; l->tail = NULL; (l->count)--; - current->prev = current->next = NULL; + current->prev = NULL; + current->next = NULL; return; } @@ -312,7 +302,8 @@ void xbt_fifo_remove_item(xbt_fifo_t l, xbt_fifo_item_t current) current->next->prev = current->prev; } (l->count)--; - current->prev = current->next = NULL; + current->prev = NULL; + current->next = NULL; } /** @@ -331,6 +322,39 @@ int xbt_fifo_is_in(xbt_fifo_t f, void *content) return 0; } +/** + * @brief Search the given element in the fifo using a comparison function + * + * This function allows to search an item with a user provided function instead + * of the pointer comparison used elsewhere in this module. Assume for example that you have a fifo of + * strings. You cannot use xbt_fifo_remove() to remove, say, "TOTO" from it because internally, xbt_fifo_remove() + * will do something like "if (item->content == "toto"), then remove it". And the pointer to the item content and the + * pointer to "toto" will never match. As a solution, the current function provides a way to search elements that are + * semantically equivalent instead of only syntactically. So, removing "Toto" from a fifo can be achieved this way: + * + * @verbatim +int my_comparison_function(void *searched, void *seen) { + return !strcmp(searched, seen); +} + + xbt_fifo_remove_item(fifo, xbt_fifo_search_item(fifo, my_comparison_function, "Toto")); +@endverbatim + * + * \param f a fifo list + * \param cmp_fun the comparison function. Prototype: void *a,void *b -> int. Semantic: returns true iff a=b + * @param closure the element to search. It will be provided as first argument to each call of cmp_fun + * \return the first item matching the comparison function, or NULL if no such item exists + */ +xbt_fifo_item_t xbt_fifo_search_item(xbt_fifo_t f, int_f_pvoid_pvoid_t cmp_fun, void *closure) { + xbt_fifo_item_t item = xbt_fifo_get_first_item(f); + while (item) { + if (cmp_fun(closure, item->content)) + return item; + item = item->next; + } + return NULL; +} + /** * \param f a list * \return a table with the objects stored in \a f. @@ -358,11 +382,9 @@ void **xbt_fifo_to_array(xbt_fifo_t f) */ xbt_fifo_t xbt_fifo_copy(xbt_fifo_t f) { - xbt_fifo_t copy = NULL; + xbt_fifo_t copy = xbt_fifo_new(); xbt_fifo_item_t b; - copy = xbt_fifo_new(); - for (b = xbt_fifo_get_first_item(f); b; b = b->next) { xbt_fifo_push(copy, b->content); } @@ -384,16 +406,16 @@ static void fifo_item_mallocator_reset_f(void *item) /** Constructor * \return a new bucket */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_new_item(void) +inline xbt_fifo_item_t xbt_fifo_new_item(void) { return xbt_mallocator_get(item_mallocator); } /** \deprecated Use #xbt_fifo_new_item instead. */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_newitem(void) +inline xbt_fifo_item_t xbt_fifo_newitem(void) { - XBT_WARN("This function is deprecated. Use xbt_fifo_new_item."); + XBT_CWARN(xbt_fifo, "This function is deprecated. Use xbt_fifo_new_item."); return xbt_fifo_new_item(); } @@ -403,7 +425,7 @@ XBT_INLINE xbt_fifo_item_t xbt_fifo_newitem(void) * * stores \a v in \a i. */ -XBT_INLINE void xbt_fifo_set_item_content(xbt_fifo_item_t i, void *v) +inline void xbt_fifo_set_item_content(xbt_fifo_item_t i, void *v) { xbt_fifo_setItemcontent(i, v); } @@ -412,7 +434,7 @@ XBT_INLINE void xbt_fifo_set_item_content(xbt_fifo_item_t i, void *v) * \param i a bucket * \return the object stored \a i. */ -XBT_INLINE void *xbt_fifo_get_item_content(xbt_fifo_item_t i) +inline void *xbt_fifo_get_item_content(xbt_fifo_item_t i) { return xbt_fifo_getItemcontent(i); } @@ -422,27 +444,25 @@ XBT_INLINE void *xbt_fifo_get_item_content(xbt_fifo_item_t i) * * Free the bucket but does not modifies the object (if any) that was stored in it. */ -XBT_INLINE void xbt_fifo_free_item(xbt_fifo_item_t b) +inline void xbt_fifo_free_item(xbt_fifo_item_t b) { xbt_mallocator_release(item_mallocator, b); - return; } /** Destructor * \deprecated Use #xbt_fifo_free_item instead. */ -XBT_INLINE void xbt_fifo_freeitem(xbt_fifo_item_t b) +inline void xbt_fifo_freeitem(xbt_fifo_item_t b) { - XBT_WARN("This function is deprecated. Use xbt_fifo_free_item."); + XBT_CWARN(xbt_fifo, "This function is deprecated. Use xbt_fifo_free_item."); xbt_fifo_free_item(b); - return; } /** * \param f a list * \return the number of buckets in \a f. */ -XBT_INLINE int xbt_fifo_size(xbt_fifo_t f) +inline int xbt_fifo_size(xbt_fifo_t f) { return f->count; } @@ -450,8 +470,10 @@ XBT_INLINE int xbt_fifo_size(xbt_fifo_t f) /** * \param l a list * \return the head of \a l. + * + * Returns NULL if the list is empty. */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_get_first_item(xbt_fifo_t l) +inline xbt_fifo_item_t xbt_fifo_get_first_item(xbt_fifo_t l) { return l->head; } @@ -459,25 +481,29 @@ XBT_INLINE xbt_fifo_item_t xbt_fifo_get_first_item(xbt_fifo_t l) /** * \param l a list * \return the tail of \a l. + * + * Returns NULL if the list is empty. */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_get_last_item(xbt_fifo_t l) +inline xbt_fifo_item_t xbt_fifo_get_last_item(xbt_fifo_t l) { return l->tail; } /** \deprecated Use #xbt_fifo_get_first_item instead. */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_getFirstItem(xbt_fifo_t l) +inline xbt_fifo_item_t xbt_fifo_getFirstItem(xbt_fifo_t l) { - XBT_WARN("This function is deprecated. Use xbt_fifo_get_first_item."); + XBT_CWARN(xbt_fifo, "This function is deprecated. Use xbt_fifo_get_first_item."); return xbt_fifo_get_first_item(l); } /** * \param i a bucket * \return the bucket that comes next + * + * Returns NULL if \a i is the tail of the list. */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_get_next_item(xbt_fifo_item_t i) +inline xbt_fifo_item_t xbt_fifo_get_next_item(xbt_fifo_item_t i) { if (i) return i->next; @@ -488,15 +514,17 @@ XBT_INLINE xbt_fifo_item_t xbt_fifo_get_next_item(xbt_fifo_item_t i) */ xbt_fifo_item_t xbt_fifo_getNextItem(xbt_fifo_item_t i) { - XBT_WARN("This function is deprecated. Use xbt_fifo_get_next_item."); + XBT_CWARN(xbt_fifo, "This function is deprecated. Use xbt_fifo_get_next_item."); return xbt_fifo_get_next_item(i); } /** * \param i a bucket * \return the bucket that is just before \a i. + * + * Returns NULL if \a i is the head of the list. */ -XBT_INLINE xbt_fifo_item_t xbt_fifo_get_prev_item(xbt_fifo_item_t i) +inline xbt_fifo_item_t xbt_fifo_get_prev_item(xbt_fifo_item_t i) { if (i) return i->prev; @@ -515,25 +543,17 @@ xbt_fifo_item_t xbt_fifo_getPrevItem(xbt_fifo_item_t i) * These are internal XBT functions called by xbt_preinit/postexit(). * It can be used several times to recreate the mallocator, for example when you switch to MC mode */ -void xbt_fifo_preinit(void) +void xbt_fifo_preinit() { - if (item_mallocator != NULL) { - /* Already created. I guess we want to switch to MC mode, so kill the previously created mallocator */ - xbt_mallocator_free(item_mallocator); - } - - item_mallocator = xbt_mallocator_new(65536, - fifo_item_mallocator_new_f, - fifo_item_mallocator_free_f, - fifo_item_mallocator_reset_f); + item_mallocator = xbt_mallocator_new(65536, fifo_item_mallocator_new_f, + fifo_item_mallocator_free_f, fifo_item_mallocator_reset_f); } -void xbt_fifo_postexit(void) +void xbt_fifo_postexit() { if (item_mallocator != NULL) { xbt_mallocator_free(item_mallocator); item_mallocator = NULL; } } - /* @} */