X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/092910cd23c789eb83b53efb69e85ae58ed3b1d0..66eeb4028730b704a90c79edc202e18a159b3eda:/src/xbt/dynar.c diff --git a/src/xbt/dynar.c b/src/xbt/dynar.c index 16a5f00e12..ca57b583a6 100644 --- a/src/xbt/dynar.c +++ b/src/xbt/dynar.c @@ -8,15 +8,19 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the license (GNU LGPL) which comes with this package. */ -#include "gras_private.h" +#include "xbt/misc.h" +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/error.h" +#include "xbt/dynar.h" +#include - -GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(dynar,GRAS); +GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(dynar,xbt,"Dynamic arrays"); struct gras_dynar_s { - size_t size; - size_t used; - size_t elmsize; + unsigned long size; + unsigned long used; + unsigned long elmsize; void *data; void_f_pvoid_t *free; }; @@ -27,55 +31,51 @@ struct gras_dynar_s { #define __sanity_check_idx(idx) \ gras_assert1(idx >= 0, \ "dynar idx(=%d) < 0", \ - idx) + (int) (idx)) #define __check_inbound_idx(dynar, idx) \ gras_assert2(idx < dynar->used, \ - "dynar is not that long. You asked %d, but it's only %d long", \ - idx, dynar->used) + "dynar is not that long. You asked %d, but it's only %lu long", \ + (int) (idx), (unsigned long) dynar->used) #define __check_sloppy_inbound_idx(dynar, idx) \ gras_assert2(idx <= dynar->used, \ - "dynar is not that long. You asked %d, but it's only %d long", \ - idx, dynar->used) + "dynar is not that long. You asked %d, but it's only %lu long", \ + (int) (idx), (unsigned long) dynar->used) #define __check_populated_dynar(dynar) \ - gras_assert0(dynar->used, \ - "dynar contains nothing") - + gras_assert1(dynar->used, \ + "dynar %p contains nothing",(void*)dynar) -static inline -void -_gras_clear_mem(void * const ptr, - const size_t length) { +static _GRAS_INLINE +void _gras_clear_mem(void * const ptr, + const unsigned long length) { memset(ptr, 0, length); } -static inline +static _GRAS_INLINE gras_error_t _gras_dynar_expand(gras_dynar_t * const dynar, const int nb) { gras_error_t errcode = no_error; - const size_t old_size = dynar->size; + const unsigned long old_size = dynar->size; if (nb > old_size) { char * const old_data = dynar->data; - const size_t elmsize = dynar->elmsize; - const size_t old_length = old_size*elmsize; + const unsigned long elmsize = dynar->elmsize; + const unsigned long old_length = old_size*elmsize; - const size_t used = dynar->used; - const size_t used_length = used*elmsize; + const unsigned long used = dynar->used; + const unsigned long used_length = used*elmsize; - const size_t new_size = nb > (2*(old_size+1)) ? nb : (2*(old_size+1)); - const size_t new_length = new_size*elmsize; - char * const new_data = calloc(1, elmsize*new_size); + const unsigned long new_size = nb > (2*(old_size+1)) ? nb : (2*(old_size+1)); + const unsigned long new_length = new_size*elmsize; + char * const new_data = gras_malloc0(elmsize*new_size); - DEBUG3("expend %p from %d to %d elements", dynar, old_size, nb); - if (!new_data) - RAISE_MALLOC; + DEBUG3("expend %p from %lu to %d elements", (void*)dynar, (unsigned long)old_size, nb); if (old_data) { memcpy(new_data, old_data, used_length); _gras_clear_mem(old_data, old_length); - free(old_data); + gras_free(old_data); } _gras_clear_mem(new_data + used_length, new_length - used_length); @@ -87,58 +87,52 @@ _gras_dynar_expand(gras_dynar_t * const dynar, return errcode; } -static inline +static _GRAS_INLINE void * _gras_dynar_elm(const gras_dynar_t * const dynar, - const size_t idx) { + const unsigned long idx) { char * const data = dynar->data; - const size_t elmsize = dynar->elmsize; + const unsigned long elmsize = dynar->elmsize; return data + idx*elmsize; } -static inline +static _GRAS_INLINE void _gras_dynar_get_elm(void * const dst, const gras_dynar_t * const dynar, - const size_t idx) { + const unsigned long idx) { void * const elm = _gras_dynar_elm(dynar, idx); - const size_t elmsize = dynar->elmsize; + const unsigned long elmsize = dynar->elmsize; memcpy(dst, elm, elmsize); } -static inline +static _GRAS_INLINE void _gras_dynar_put_elm(const gras_dynar_t * const dynar, - const size_t idx, + const unsigned long idx, const void * const src) { void * const elm = _gras_dynar_elm(dynar, idx); - const size_t elmsize = dynar->elmsize; + const unsigned long elmsize = dynar->elmsize; memcpy(elm, src, elmsize); } /** * gras_dynar_new: - * @whereto: pointer to where the dynar should be created * @elm_size: size of each element in the dynar * @free_func: function to call each time we want to get rid of an element (or NULL if nothing to do). - * @Returns: malloc_error or no_error * * Creates a new dynar. If a free_func is provided, the elements have to be * pointer of pointer. That is to say that dynars can contain either base * types (int, char, double, etc) or pointer of pointers (struct **). */ -gras_error_t -gras_dynar_new(gras_dynar_t ** const p_dynar, - const size_t elmsize, - void_f_pvoid_t * const free_func) { - gras_error_t errcode = no_error; - gras_dynar_t *dynar = NULL; - - if (!(dynar = calloc(1, sizeof(gras_dynar_t)))) - RAISE_MALLOC; +gras_dynar_t * +gras_dynar_new(const unsigned long elmsize, + void_f_pvoid_t * const free_func) { + + gras_dynar_t *dynar = gras_new0(gras_dynar_t,1); dynar->size = 0; dynar->used = 0; @@ -146,9 +140,7 @@ gras_dynar_new(gras_dynar_t ** const p_dynar, dynar->data = NULL; dynar->free = free_func; - *p_dynar = dynar; - - return errcode; + return dynar; } /** @@ -164,12 +156,12 @@ gras_dynar_free_container(gras_dynar_t * const dynar) { if (dynar->data) { _gras_clear_mem(dynar->data, dynar->size); - free(dynar->data); + gras_free(dynar->data); } _gras_clear_mem(dynar, sizeof(gras_dynar_t)); - free(dynar); + gras_free(dynar); } } @@ -184,13 +176,14 @@ gras_dynar_reset(gras_dynar_t * const dynar) { __sanity_check_dynar(dynar); + DEBUG1("Reset the dynar %p",(void*)dynar); if (dynar->free) { gras_dynar_map(dynar, dynar->free); } if (dynar->data) { _gras_clear_mem(dynar->data, dynar->size); - free(dynar->data); + gras_free(dynar->data); } dynar->size = 0; @@ -219,9 +212,29 @@ gras_dynar_free(gras_dynar_t * const dynar) { * * Returns the count of elements in a dynar */ -size_t +unsigned long gras_dynar_length(const gras_dynar_t * const dynar) { - return (dynar ? dynar->used : (size_t)0); + return (dynar ? (unsigned long) dynar->used : (unsigned long)0); +} + +/** + * gras_dynar_get_cpy: + * @dynar: information dealer + * @idx: index of the slot we want to retrive + * @dst: where to pu the result to. + * + * Retrieve a copy of the Nth element of a dynar. + */ +void +gras_dynar_get_cpy(const gras_dynar_t * const dynar, + const int idx, + void * const dst) { + + __sanity_check_dynar(dynar); + __sanity_check_idx(idx); + __check_inbound_idx(dynar, idx); + + _gras_dynar_get_elm(dst, dynar, idx); } /** @@ -233,16 +246,15 @@ gras_dynar_length(const gras_dynar_t * const dynar) { * Retrieve the Nth element of a dynar. Warning, the returned value is the actual content of * the dynar. Make a copy before fooling with it. */ -void -gras_dynar_get(const gras_dynar_t * const dynar, - const int idx, - void * const dst) { +void* +gras_dynar_get_ptr(const gras_dynar_t * const dynar, + const int idx) { __sanity_check_dynar(dynar); __sanity_check_idx(idx); __check_inbound_idx(dynar, idx); - _gras_dynar_get_elm(dst, dynar, idx); + return _gras_dynar_elm(dynar, idx); } /** @@ -250,30 +262,26 @@ gras_dynar_get(const gras_dynar_t * const dynar, * @dynar: * @idx: * @src: What will be feeded to the dynar - * @Returns: malloc_error or no_error * * Set the Nth element of a dynar, expanding the dynar if needed, BUT NOT freeing * the previous value at this position. If you want to free the previous content, * use gras_dynar_remplace(). */ -gras_error_t +void gras_dynar_set(gras_dynar_t * const dynar, const int idx, const void * const src) { - gras_error_t errcode = no_error; __sanity_check_dynar(dynar); __sanity_check_idx(idx); - TRY(_gras_dynar_expand(dynar, idx+1)); + _gras_dynar_expand(dynar, idx+1); if (idx >= dynar->used) { dynar->used = idx+1; } _gras_dynar_put_elm(dynar, idx, src); - - return errcode; } /** @@ -281,17 +289,15 @@ gras_dynar_set(gras_dynar_t * const dynar, * @dynar: * @idx: * @object: - * @Returns: malloc_error or no_error * * Set the Nth element of a dynar, expanding the dynar if needed, AND DO * free the previous value at this position. If you don't want to free the * previous content, use gras_dynar_set(). */ -gras_error_t +void gras_dynar_remplace(gras_dynar_t * const dynar, const int idx, const void * const object) { - gras_error_t errcode = no_error; __sanity_check_dynar(dynar); __sanity_check_idx(idx); @@ -302,9 +308,7 @@ gras_dynar_remplace(gras_dynar_t * const dynar, dynar->free(old_object); } - errcode = gras_dynar_set(dynar, idx, object); - - return errcode; + gras_dynar_set(dynar, idx, object); } /** @@ -312,33 +316,31 @@ gras_dynar_remplace(gras_dynar_t * const dynar, * @dynar: * @idx: * @src: What will be feeded to the dynar - * @Returns: malloc_error or no_error * * Set the Nth element of a dynar, expanding the dynar if needed, and * moving the previously existing value and all subsequent ones to one * position right in the dynar. */ -gras_error_t +void gras_dynar_insert_at(gras_dynar_t * const dynar, const int idx, const void * const src) { - gras_error_t errcode = no_error; __sanity_check_dynar(dynar); __sanity_check_idx(idx); __check_sloppy_inbound_idx(dynar, idx); { - const size_t old_used = dynar->used; - const size_t new_used = old_used + 1; + const unsigned long old_used = dynar->used; + const unsigned long new_used = old_used + 1; - TRY(_gras_dynar_expand(dynar, new_used)); + _gras_dynar_expand(dynar, new_used); { - const size_t nb_shift = old_used - idx; - const size_t elmsize = dynar->elmsize; + const unsigned long nb_shift = old_used - idx; + const unsigned long elmsize = dynar->elmsize; - const size_t offset = nb_shift*elmsize; + const unsigned long offset = nb_shift*elmsize; void * const elm_src = _gras_dynar_elm(dynar, idx); void * const elm_dst = _gras_dynar_elm(dynar, idx+1); @@ -349,8 +351,6 @@ gras_dynar_insert_at(gras_dynar_t * const dynar, _gras_dynar_put_elm(dynar, idx, src); dynar->used = new_used; } - - return errcode; } /** @@ -375,13 +375,13 @@ gras_dynar_remove_at(gras_dynar_t * const dynar, _gras_dynar_get_elm(object, dynar, idx); { - const size_t old_used = dynar->used; - const size_t new_used = old_used - 1; + const unsigned long old_used = dynar->used; + const unsigned long new_used = old_used - 1; - const size_t nb_shift = old_used-1 - idx; - const size_t elmsize = dynar->elmsize; + const unsigned long nb_shift = old_used-1 - idx; + const unsigned long elmsize = dynar->elmsize; - const size_t offset = nb_shift*elmsize; + const unsigned long offset = nb_shift*elmsize; void * const elm_src = _gras_dynar_elm(dynar, idx+1); void * const elm_dst = _gras_dynar_elm(dynar, idx); @@ -396,15 +396,14 @@ gras_dynar_remove_at(gras_dynar_t * const dynar, * gras_dynar_push: * @dynar: * @src: - * @Returns: malloc_error or no_error * * Add an element at the end of the dynar */ -gras_error_t +void gras_dynar_push(gras_dynar_t * const dynar, const void * const src) { __sanity_check_dynar(dynar); - return gras_dynar_insert_at(dynar, dynar->used, src); + gras_dynar_insert_at(dynar, dynar->used, src); } /** @@ -419,6 +418,7 @@ gras_dynar_pop(gras_dynar_t * const dynar, void * const dst) { __sanity_check_dynar(dynar); __check_populated_dynar(dynar); + DEBUG1("Pop %p",(void*)dynar); gras_dynar_remove_at(dynar, dynar->used-1, dst); } @@ -426,16 +426,15 @@ gras_dynar_pop(gras_dynar_t * const dynar, * gras_dynar_unshift: * @dynar: * @src: - * @Returns: malloc_error or no_error * * Add an element at the begining of the dynar (rather long, Use * gras_dynar_push() when possible) */ -gras_error_t +void gras_dynar_unshift(gras_dynar_t * const dynar, const void * const src) { __sanity_check_dynar(dynar); - return gras_dynar_insert_at(dynar, 0, src); + gras_dynar_insert_at(dynar, 0, src); } /** @@ -471,8 +470,8 @@ gras_dynar_map(const gras_dynar_t * const dynar, { char elm[64]; - const size_t used = dynar->used; - size_t i = 0; + const unsigned long used = dynar->used; + unsigned long i = 0; for (i = 0; i < used; i++) { _gras_dynar_get_elm(elm, dynar, i); @@ -497,7 +496,7 @@ gras_dynar_cursor_first(const gras_dynar_t * const dynar, int * const cursor) { __sanity_check_dynar(dynar); - DEBUG1("Set cursor on %p to the first position",dynar); + DEBUG1("Set cursor on %p to the first position",(void*)dynar); *cursor = 0; } @@ -530,10 +529,10 @@ gras_dynar_cursor_get(const gras_dynar_t * const dynar, const int idx = *cursor; if (idx >= dynar->used) { - DEBUG1("Cursor on %p already on last elem",dynar); + DEBUG1("Cursor on %p already on last elem",(void*)dynar); return FALSE; } - DEBUG2("Cash out cursor on %p at %d",dynar,idx); + DEBUG2("Cash out cursor on %p at %d",(void*)dynar,idx); _gras_dynar_get_elm(dst, dynar, idx); } @@ -546,10 +545,27 @@ gras_dynar_cursor_get(const gras_dynar_t * const dynar, * @dynar: * @cursor: * - * Remove the entry pointed by the cursor, for use in the middle of a foreach + * Remove (free) the entry pointed by the cursor, for use in the middle of a foreach */ void gras_dynar_cursor_rm(gras_dynar_t * dynar, int * const cursor) { - - gras_dynar_remove_at(dynar,(*cursor)--,NULL); + void *dst; + + if (dynar->elmsize > sizeof(void*)) { + DEBUG0("Elements too big to fit into a pointer"); + if (dynar->free) { + dst=gras_malloc(dynar->elmsize); + gras_dynar_remove_at(dynar,(*cursor)--,dst); + (dynar->free)(dst); + gras_free(dst); + } else { + DEBUG0("Ok, we dont care about the element when no free function"); + gras_dynar_remove_at(dynar,(*cursor)--,NULL); + } + + } else { + gras_dynar_remove_at(dynar,(*cursor)--,&dst); + if (dynar->free) + (dynar->free)(dst); + } }