X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/e3f8483759ed01e7332f2cb243e8c42ea9ab23f6..b9e946cdde00d87529a22bd6e152357d8e71e935:/src/xbt/dynar.c diff --git a/src/xbt/dynar.c b/src/xbt/dynar.c index 8414788c99..f29b2806c8 100644 --- a/src/xbt/dynar.c +++ b/src/xbt/dynar.c @@ -27,10 +27,10 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_dyn,xbt,"Dynamic arrays"); #define _dynar_lock(dynar) \ if (dynar->mutex) \ - xbt_mutex_lock(dynar->mutex) + xbt_mutex_acquire(dynar->mutex) #define _dynar_unlock(dynar) \ if (dynar->mutex) \ - xbt_mutex_unlock(dynar->mutex) + xbt_mutex_release(dynar->mutex) #define _sanity_check_dynar(dynar) \ xbt_assert0(dynar, \ "dynar is NULL") @@ -53,6 +53,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_dyn,xbt,"Dynamic arrays"); THROW1(bound_error,0, \ "dynar %p is empty", dynar) +static void _dynar_map(const xbt_dynar_t dynar, + void_f_pvoid_t const op); static XBT_INLINE void _xbt_clear_mem(void * const ptr, @@ -63,7 +65,7 @@ void _xbt_clear_mem(void * const ptr, static XBT_INLINE void _xbt_dynar_expand(xbt_dynar_t const dynar, - const int nb) { + const unsigned long nb) { const unsigned long old_size = dynar->size; if (nb > old_size) { @@ -79,7 +81,7 @@ _xbt_dynar_expand(xbt_dynar_t const dynar, const unsigned long new_length = new_size*elmsize; char * const new_data = (char *) xbt_malloc0(elmsize*new_size); - DEBUG3("expend %p from %lu to %d elements", (void*)dynar, (unsigned long)old_size, nb); + DEBUG3("expend %p from %lu to %lu elements", (void*)dynar, (unsigned long)old_size, nb); if (old_data) { memcpy(new_data, old_data, used_length); @@ -128,7 +130,7 @@ _xbt_dynar_put_elm(const xbt_dynar_t dynar, static XBT_INLINE void _xbt_dynar_remove_at(xbt_dynar_t const dynar, - const int idx, + const unsigned long idx, void * const object) { unsigned long nb_shift; @@ -180,7 +182,7 @@ xbt_dynar_dump(xbt_dynar_t dynar) { */ xbt_dynar_t xbt_dynar_new(const unsigned long elmsize, - void_f_pvoid_t * const free_f) { + void_f_pvoid_t const free_f) { xbt_dynar_t dynar = xbt_new0(s_xbt_dynar_t,1); @@ -201,7 +203,7 @@ xbt_dynar_new(const unsigned long elmsize, */ xbt_dynar_t xbt_dynar_new_sync(const unsigned long elmsize, - void_f_pvoid_t * const free_f) { + void_f_pvoid_t const free_f) { xbt_dynar_t res = xbt_dynar_new(elmsize,free_f); res->mutex = xbt_mutex_init(); return res; @@ -245,7 +247,7 @@ xbt_dynar_reset(xbt_dynar_t const dynar) { DEBUG1("Reset the dynar %p",(void*)dynar); if (dynar->free_f) { - xbt_dynar_map(dynar, dynar->free_f); + _dynar_map(dynar, dynar->free_f); } /* if (dynar->data) @@ -276,7 +278,7 @@ xbt_dynar_reset(xbt_dynar_t const dynar) { * array is not expanded and nothing is done. */ void xbt_dynar_shrink(xbt_dynar_t dynar, int empty_slots_wanted) { - int size_wanted; + unsigned long size_wanted; _dynar_lock(dynar); @@ -324,7 +326,7 @@ xbt_dynar_length(const xbt_dynar_t dynar) { */ void xbt_dynar_get_cpy(const xbt_dynar_t dynar, - const int idx, + const unsigned long idx, void * const dst) { _dynar_lock(dynar); _sanity_check_dynar(dynar); @@ -345,7 +347,7 @@ xbt_dynar_get_cpy(const xbt_dynar_t dynar, * Make a copy before fooling with it. */ void* -xbt_dynar_get_ptr(const xbt_dynar_t dynar, const int idx) { +xbt_dynar_get_ptr(const xbt_dynar_t dynar, const unsigned long idx) { void *res; _dynar_lock(dynar); @@ -361,7 +363,7 @@ xbt_dynar_get_ptr(const xbt_dynar_t dynar, const int idx) { static void XBT_INLINE /* not synchronized */ _xbt_dynar_set(xbt_dynar_t dynar, - const int idx, + const unsigned long idx, const void * const src) { _sanity_check_dynar(dynar); @@ -406,7 +408,7 @@ xbt_dynar_set(xbt_dynar_t dynar, */ void xbt_dynar_replace(xbt_dynar_t dynar, - const int idx, + const unsigned long idx, const void * const object) { _dynar_lock(dynar); _sanity_check_dynar(dynar); @@ -415,7 +417,7 @@ xbt_dynar_replace(xbt_dynar_t dynar, if (idx < dynar->used && dynar->free_f) { void * const old_object = _xbt_dynar_elm(dynar, idx); - dynar->free_f(old_object); + (*(dynar->free_f))(old_object); } _xbt_dynar_set(dynar, idx, object); @@ -424,7 +426,7 @@ xbt_dynar_replace(xbt_dynar_t dynar, static XBT_INLINE void * _xbt_dynar_insert_at_ptr(xbt_dynar_t const dynar, - const int idx) { + const unsigned long idx) { void *res; unsigned long old_used; unsigned long new_used; @@ -501,7 +503,7 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar, void * const object) { _dynar_lock(dynar); - _xbt_dynar_remove_at(dynar, idx, object); + _xbt_dynar_remove_at(dynar, idx, object); _dynar_unlock(dynar); } @@ -512,7 +514,7 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar, int xbt_dynar_search(xbt_dynar_t const dynar, void *const elem) { - int it; + unsigned long it; _dynar_lock(dynar); for (it=0; it< dynar->used; it++) @@ -523,7 +525,6 @@ xbt_dynar_search(xbt_dynar_t const dynar, _dynar_unlock(dynar); THROW2(not_found_error,0,"Element %p not part of dynar %p",elem,dynar); - return -1; } /** @brief Returns a boolean indicating whether the element is part of the dynar */ @@ -552,15 +553,27 @@ xbt_dynar_member(xbt_dynar_t const dynar, */ void * xbt_dynar_push_ptr(xbt_dynar_t const dynar) { - return xbt_dynar_insert_at_ptr(dynar, dynar->used); + void *res; + + /* we have to inline xbt_dynar_insert_at_ptr here to make sure that + dynar->used don't change between reading it and getting the lock + within xbt_dynar_insert_at_ptr */ + _dynar_lock(dynar); + res = _xbt_dynar_insert_at_ptr(dynar,dynar->used); + _dynar_unlock(dynar); + return res; } /** @brief Add an element at the end of the dynar */ void xbt_dynar_push(xbt_dynar_t const dynar, const void * const src) { - /* sanity checks done by insert_at */ - xbt_dynar_insert_at(dynar, dynar->used, src); + _dynar_lock(dynar); + /* checks done in xbt_dynar_insert_at_ptr */ + memcpy(_xbt_dynar_insert_at_ptr(dynar,dynar->used), + src, + dynar->elmsize); + _dynar_unlock(dynar); } /** @brief Mark the last dynar's element as unused and return a pointer to it. @@ -588,7 +601,9 @@ xbt_dynar_pop(xbt_dynar_t const dynar, /* sanity checks done by remove_at */ DEBUG1("Pop %p",(void*)dynar); - xbt_dynar_remove_at(dynar, dynar->used-1, dst); + _dynar_lock(dynar); + _xbt_dynar_remove_at(dynar, dynar->used-1, dst); + _dynar_unlock(dynar); } /** @brief Add an element at the begining of the dynar. @@ -615,6 +630,18 @@ xbt_dynar_shift(xbt_dynar_t const dynar, xbt_dynar_remove_at(dynar, 0, dst); } +static void _dynar_map(const xbt_dynar_t dynar, + void_f_pvoid_t const op) { + char elm[SIZEOF_MAX]; + const unsigned long used = dynar->used; + unsigned long i = 0; + + for (i = 0; i < used; i++) { + _xbt_dynar_get_elm(elm, dynar, i); + (*op)(elm); + } +} + /** @brief Apply a function to each member of a dynar * * The mapped function may change the value of the element itself, @@ -626,21 +653,13 @@ xbt_dynar_shift(xbt_dynar_t const dynar, */ void xbt_dynar_map(const xbt_dynar_t dynar, - void_f_pvoid_t * const op) { + void_f_pvoid_t const op) { _dynar_lock(dynar); _sanity_check_dynar(dynar); - { - char elm[SIZEOF_MAX]; - const unsigned long used = dynar->used; - unsigned long i = 0; + _dynar_map(dynar,op); - for (i = 0; i < used; i++) { - _xbt_dynar_get_elm(elm, dynar, i); - op(elm); - } - } _dynar_unlock(dynar); } @@ -653,7 +672,7 @@ xbt_dynar_map(const xbt_dynar_t dynar, */ void _xbt_dynar_cursor_first(const xbt_dynar_t dynar, - int * const cursor) { + unsigned int * const cursor) { _dynar_lock(dynar); DEBUG1("Set cursor on %p to the first position",(void*)dynar); @@ -666,7 +685,7 @@ _xbt_dynar_cursor_first(const xbt_dynar_t dynar, */ void _xbt_dynar_cursor_step(const xbt_dynar_t dynar, - int * const cursor) { + unsigned int * const cursor) { (*cursor)++; } @@ -677,20 +696,20 @@ _xbt_dynar_cursor_step(const xbt_dynar_t dynar, */ int _xbt_dynar_cursor_get(const xbt_dynar_t dynar, - int * const cursor, + unsigned int * const cursor, void * const dst) { _sanity_check_dynar(dynar); { - const int idx = *cursor; + const unsigned long idx = *cursor; if (idx >= dynar->used) { DEBUG1("Cursor on %p already on last elem",(void*)dynar); _dynar_unlock(dynar); return FALSE; } - DEBUG2("Cash out cursor on %p at %d",(void*)dynar,idx); + DEBUG2("Cash out cursor on %p at %lu",(void*)dynar,idx); _xbt_dynar_get_elm(dst, dynar, idx); } @@ -703,7 +722,7 @@ _xbt_dynar_cursor_get(const xbt_dynar_t dynar, * This function can be used while traversing without problem. */ void xbt_dynar_cursor_rm(xbt_dynar_t dynar, - int * const cursor) { + unsigned int * const cursor) { _xbt_dynar_remove_at(dynar,(*cursor)--,NULL); } @@ -729,7 +748,8 @@ XBT_LOG_DEFAULT_CATEGORY(xbt_dyn); XBT_TEST_UNIT("int",test_dynar_int,"Dynars of integers") { /* Vars_decl [doxygen cruft] */ xbt_dynar_t d; - int i,cpt,cursor; + int i,cpt; + unsigned int cursor; int *iptr; xbt_test_add0("==== Traverse the empty dynar"); @@ -874,7 +894,8 @@ XBT_TEST_UNIT("int",test_dynar_int,"Dynars of integers") { /*******************************************************************************/ XBT_TEST_UNIT("double",test_dynar_double,"Dynars of doubles") { xbt_dynar_t d; - int cpt,cursor; + int cpt; + unsigned int cursor; double d1,d2; xbt_test_add0("==== Traverse the empty dynar"); @@ -995,12 +1016,13 @@ static void free_string(void *d){ XBT_TEST_UNIT("string",test_dynar_string,"Dyars of strings") { xbt_dynar_t d; int cpt; + unsigned int iter; char buf[1024]; char *s1,*s2; xbt_test_add0("==== Traverse the empty dynar"); d=xbt_dynar_new(sizeof(char *),&free_string); - xbt_dynar_foreach(d,cpt,s1){ + xbt_dynar_foreach(d,iter,s1){ xbt_test_assert0(FALSE, "Damnit, there is something in the empty dynar"); } @@ -1051,8 +1073,8 @@ XBT_TEST_UNIT("string",test_dynar_string,"Dyars of strings") { xbt_dynar_unshift(d,&s1); } /* 2. Traverse the dynar with the macro */ - xbt_dynar_foreach(d,cpt,s1) { - sprintf(buf,"%d",NB_ELEM - cpt -1); + xbt_dynar_foreach(d,iter,s1) { + sprintf(buf,"%d",NB_ELEM - iter -1); xbt_test_assert2 (!strcmp(buf,s1), "The retrieved value is not the same than the injected one (%s!=%s)", buf,s1);