From dd65c1fbeceec3e8a0550dc98ea530366ff8821f Mon Sep 17 00:00:00 2001 From: mquinson Date: Sat, 3 Jul 2004 04:14:06 +0000 Subject: [PATCH] Fix the ugly case of reference to dynamic array. The size of this array comes from the network. It is needed both at the reference reception level (to allocate enough space) and at the array reception level (to fill enough room). It is then passed as an argument of the recursive function. This is a crude hack, but I was told that working code is sometimes better than neat one ;) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@147 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- changelog | 6 ++- src/gras/DataDesc/datadesc.c | 5 ++- src/gras/DataDesc/ddt_exchange.c | 65 +++++++++++++++++++++----------- testsuite/gras/datadesc_usage.c | 14 ++----- 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/changelog b/changelog index f96da964ee..a2c6a7ef40 100644 --- a/changelog +++ b/changelog @@ -1,6 +1,8 @@ 2004-07-03 - - Create a new log channel tbx containing dict, set, log, dynar (to shut - them all up in one shot) + - Create a new log channel tbx containing dict, set, log, dynar (to shut + them all up in one shot) + [DataDesc] + - Fix the ugly case of reference to dynamic array. 2004-06-21 [Transport] diff --git a/src/gras/DataDesc/datadesc.c b/src/gras/DataDesc/datadesc.c index 926eb98165..6fc86b2191 100644 --- a/src/gras/DataDesc/datadesc.c +++ b/src/gras/DataDesc/datadesc.c @@ -128,9 +128,12 @@ gras_datadesc_init(void) { e_gras_dd_scalar_encoding_float, NULL,&ddt)); - TRYFAIL(gras_datadesc_declare_array_dyn("string", + TRYFAIL(gras_datadesc_declare_array_dyn("char[]", gras_datadesc_by_name("char"), _strlen_cb,&ddt)); + TRYFAIL(gras_datadesc_declare_ref("string", + gras_datadesc_by_name("char[]"), + &ddt)); } diff --git a/src/gras/DataDesc/ddt_exchange.c b/src/gras/DataDesc/ddt_exchange.c index 075cffd4c5..3727964ea1 100644 --- a/src/gras/DataDesc/ddt_exchange.c +++ b/src/gras/DataDesc/ddt_exchange.c @@ -43,7 +43,8 @@ gras_datadesc_recv_rec(gras_socket_t *sock, int r_arch, char **r_data, long int r_lgr, - char *dst); + char *dst, + int subsize); static gras_error_t @@ -500,6 +501,13 @@ gras_error_t gras_datadesc_send(gras_socket_t *sock, * gras_datadesc_recv_rec: * * Do the data reception job recursively. + * + * subsize used only to deal with vicious case of reference to dynamic array. + * This size is needed at the reference reception level (to allocate enough + * space) and at the array reception level (to fill enough room). + * + * Having this size passed as an argument of the recursive function is a crude + * hack, but I was told that working code is sometimes better than neat one ;) */ gras_error_t gras_datadesc_recv_rec(gras_socket_t *sock, @@ -509,7 +517,8 @@ gras_datadesc_recv_rec(gras_socket_t *sock, int r_arch, char **r_data, long int r_lgr, - char *l_data) { + char *l_data, + int subsize) { gras_error_t errcode; int cpt; @@ -546,7 +555,7 @@ gras_datadesc_recv_rec(gras_socket_t *sock, TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type, r_arch,NULL,0, - field_data)); + field_data,-1)); } VERB1("<< Received all fields of the structure %s", type->name); @@ -576,7 +585,7 @@ gras_datadesc_recv_rec(gras_socket_t *sock, TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type, r_arch,NULL,0, - l_data)); + l_data,-1)); break; } @@ -618,27 +627,45 @@ gras_datadesc_recv_rec(gras_socket_t *sock, if (errcode == mismatch_error) { + int subsubcount = -1; void *l_referenced=NULL; TRY(gras_datadesc_by_id(ref_code, &sub_type)); - VERB1("Receiving '%s' ",sub_type->name); - TRY(gras_dd_alloc_ref(refs,sub_type->size[GRAS_THISARCH], - r_ref,pointer_type->size[r_arch], (char**)&l_referenced)); - - VERB2("Receiving '%s' remotely referenced at %p", + VERB2("Receiving a ref to '%s', remotely @%p", sub_type->name, *(void**)r_ref); + if (sub_type->category_code == e_gras_datadesc_type_cat_array) { + /* Damn. Reference to a dynamic array. Allocating the size for it + is more complicated */ + gras_dd_cat_array_t array_data = sub_type->category.array_data; + gras_datadesc_type_t *subsub_type; + + subsubcount = array_data.fixed_size; + if (subsubcount < 0) + TRY(gras_dd_recv_int(sock, r_arch, &subsubcount)); + + TRY(gras_datadesc_by_id(array_data.code, &subsub_type)); + + + TRY(gras_dd_alloc_ref(refs, + subsub_type->size[GRAS_THISARCH] * subsubcount, + r_ref,pointer_type->size[r_arch], + (char**)&l_referenced)); + } else { + TRY(gras_dd_alloc_ref(refs,sub_type->size[GRAS_THISARCH], + r_ref,pointer_type->size[r_arch], + (char**)&l_referenced)); + } - // DEBUG2("l_ref= %p; &l_ref=%p",l_referenced,&l_referenced); TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type, r_arch,r_ref,pointer_type->size[r_arch], - (char*)l_referenced)); + (char*)l_referenced, subsubcount)); *(void**)l_data=l_referenced; VERB3("'%s' remotely referenced at %p locally at %p", sub_type->name, *(void**)r_ref, l_referenced); } else if (errcode == no_error) { - VERB2("NOT receiving data remotely referenced @%p (already done, locally @%p). ", + VERB2("NOT receiving data remotely referenced @%p (already done, @%p here)", *(void**)r_ref, *(void**)l_ref); *(void**)l_data=*l_ref; @@ -657,8 +684,10 @@ gras_datadesc_recv_rec(gras_socket_t *sock, long int elm_size; array_data = type->category.array_data; - /* determine element count locally or from peer */ + /* determine element count locally, or from caller, or from peer */ count = array_data.fixed_size; + if (count <= 0) + count = subsize; if (count <= 0) TRY(gras_dd_recv_int(sock, r_arch, &count)); if (count < 0) @@ -670,14 +699,10 @@ gras_datadesc_recv_rec(gras_socket_t *sock, elm_size = sub_type->aligned_size[GRAS_THISARCH]; VERB2("Receive a %d-long array of %s",count, sub_type->name); - if (!l_data) { - TRY(gras_dd_alloc_ref(refs,elm_size*count,r_data,r_lgr, &l_data)); - } - ptr = l_data; for (cpt=0; cpt