X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/e1b2e70eb620dda84721dd3b5b8c9d60ca0ae4ce..3c7b741ce2f591d3f8ebfd44aaa136d99e06fae8:/src/gras/DataDesc/datadesc.c diff --git a/src/gras/DataDesc/datadesc.c b/src/gras/DataDesc/datadesc.c index 74786f7934..dcccee2b10 100644 --- a/src/gras/DataDesc/datadesc.c +++ b/src/gras/DataDesc/datadesc.c @@ -1,490 +1,257 @@ -/* $Id$ */ - /* datadesc - data description in order to send/recv it in GRAS */ -/* Authors: Olivier Aumage, Martin Quinson */ -/* Copyright (C) 2003, 2004 the GRAS posse. */ +/* Copyright (c) 2004, 2005, 2006, 2007, 2009, 2010. The SimGrid Team. + * All rights reserved. */ /* 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 "DataDesc/datadesc_private.h" - -GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(DataDesc,GRAS); -gras_set_t *gras_datadesc_set_local=NULL; - -/** - * gras_datadesc_init: - * - * Initialize the datadesc module - **/ -void -gras_datadesc_init(void) { - gras_error_t errcode; - - VERB0("Initializing DataDesc"); - errcode = gras_set_new(&gras_datadesc_set_local); - gras_assert0(errcode==no_error, - "Impossible to create the data set containg locally known types"); -} - -/** - * gras_datadesc_exit: - * - * Finalize the datadesc module - **/ -void -gras_datadesc_exit(void) { - VERB0("Exiting DataDesc"); - gras_set_free(&gras_datadesc_set_local); -} + * under the terms of the license (GNU LGPL) which comes with this package. */ -/*** - *** CREATION FUNCTIONS: private to this file - ***/ -static gras_error_t -gras_ddt_new(const char *name, - gras_datadesc_type_t **dst) { - - gras_datadesc_type_t *res=malloc(sizeof(gras_datadesc_type_t)); - if (!res) - RAISE_MALLOC; - - memset(res, 0, sizeof(res)); - res->name = strdup(name); - - *dst=res; - return no_error; -} +#include "gras/DataDesc/datadesc_private.h" -/** - * gras_ddt_new_scalar: - * - * Create a new scalar and give a pointer to it - */ -gras_error_t -gras_ddt_new_scalar(const char *name, - long int size, - enum e_gras_dd_scalar_encoding encoding, - gras_datadesc_type_cb_void_t cb, - gras_datadesc_type_t **dst) { - - gras_error_t errcode; - gras_datadesc_type_t *res; - - TRY(gras_ddt_new(name,dst)); - res=*dst; - - res->size = size>0 ? size : 0; - - if (size>0) { /* Black magic from Oli FIXME: documentation ;)*/ - long int sz = size; - long int mask = sz; - - while ((sz >>= 1)) { - mask |= sz; - } +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_ddt, gras, "Data description"); +/* FIXME: make this host-dependent using a trick such as UserData*/ +/*@null@*/ xbt_set_t gras_datadesc_set_local = NULL; - if (size & (mask >> 1)) { - res->alignment = (size & ~(mask >> 1)) << 1; - gras_assert0(res->alignment != 0, - "scalar type too large"); - - res->aligned_size = aligned(size, res->alignment); - gras_assert0 (res->aligned_size >= 0, - "scalar type too large"); - - } else { - res->alignment = size & ~(mask >> 1);; - res->aligned_size = aligned(size, res->alignment); - } - - } else { - res->alignment = 0; - res->aligned_size = 0; - } - res->category_code = e_gras_datadesc_type_cat_scalar; - res->category.scalar_data.encoding = encoding; +/* callback for array size when sending strings */ +static int _strlen_cb( /*@unused@ */ gras_datadesc_type_t type, /*@unused@ */ + gras_cbps_t vars, void *data) +{ - res->pre = cb; - return no_error; + return 1 + (int) strlen(data); } /** - * gras_dd_cat_field_free: + * gras_datadesc_init: * - * Frees one struct or union field - */ -void gras_dd_cat_field_free(void *f) { - gras_dd_cat_field_t *field = (gras_dd_cat_field_t *)f; - if (field) { - if (field->name) - free(field->name); - free(field); - } -} + * Initialize the datadesc module. + * FIXME: We assume that when neither signed nor unsigned is given, + * that means signed. To be checked by configure. + **/ +void gras_datadesc_init(void) +{ + gras_datadesc_type_t ddt; /* What to add */ + + /* only initialize once */ + if (gras_datadesc_set_local != NULL) + return; + + XBT_VERB("Initializing DataDesc"); + + gras_datadesc_set_local = xbt_set_new(); + + + /* all known datatypes */ + + ddt = gras_datadesc_scalar("signed char", + gras_ddt_scalar_char, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("char", + gras_ddt_scalar_char, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("unsigned char", + gras_ddt_scalar_char, + e_gras_dd_scalar_encoding_uint); + + ddt = gras_datadesc_scalar("signed short int", + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("short int", + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("short", + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("unsigned short int", + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_uint); + + ddt = gras_datadesc_scalar("signed int", + gras_ddt_scalar_int, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("int", + gras_ddt_scalar_int, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("unsigned int", + gras_ddt_scalar_int, + e_gras_dd_scalar_encoding_uint); + + ddt = gras_datadesc_scalar("signed long int", + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("long int", + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("long", + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("unsigned long int", + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_uint); + + ddt = gras_datadesc_scalar("signed long long int", + gras_ddt_scalar_long_long, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("long long int", + gras_ddt_scalar_long_long, + e_gras_dd_scalar_encoding_sint); + ddt = gras_datadesc_scalar("unsigned long long int", + gras_ddt_scalar_long_long, + e_gras_dd_scalar_encoding_uint); + + ddt = gras_datadesc_scalar("data pointer", + gras_ddt_scalar_pdata, + e_gras_dd_scalar_encoding_uint); + ddt = gras_datadesc_scalar("function pointer", + gras_ddt_scalar_pfunc, + e_gras_dd_scalar_encoding_uint); + + ddt = gras_datadesc_scalar("float", + gras_ddt_scalar_float, + e_gras_dd_scalar_encoding_float); + ddt = gras_datadesc_scalar("double", + gras_ddt_scalar_double, + e_gras_dd_scalar_encoding_float); + + ddt = gras_datadesc_array_dyn("char[]", + gras_datadesc_by_name("char"), _strlen_cb); + gras_datadesc_ref("string", ddt); + gras_datadesc_ref("xbt_string_t", ddt); + + /* specific datatype: the exception type (for RPC) */ + ddt = gras_datadesc_struct("ex_t"); + gras_datadesc_struct_append(ddt, "msg", gras_datadesc_by_name("string")); + gras_datadesc_struct_append(ddt, "category", + gras_datadesc_by_name("int")); + gras_datadesc_struct_append(ddt, "value", gras_datadesc_by_name("int")); + + gras_datadesc_struct_append(ddt, "remote", + gras_datadesc_by_name("short int")); + + gras_datadesc_struct_append(ddt, "host", + gras_datadesc_by_name("string")); + gras_datadesc_struct_append(ddt, "procname", + gras_datadesc_by_name("string")); + gras_datadesc_struct_append(ddt, "pid", + gras_datadesc_by_name("long int")); + gras_datadesc_struct_append(ddt, "file", + gras_datadesc_by_name("string")); + gras_datadesc_struct_append(ddt, "line", gras_datadesc_by_name("int")); + gras_datadesc_struct_append(ddt, "func", + gras_datadesc_by_name("string")); + gras_datadesc_struct_append(ddt, "used", gras_datadesc_by_name("int")); + gras_datadesc_cb_field_push(ddt, "used"); + gras_datadesc_struct_append(ddt, "bt_strings", + gras_datadesc_ref_pop_arr + (gras_datadesc_by_name("string"))); + + gras_datadesc_struct_close(ddt); + + /* specific datatype: xbt_peer_t */ + ddt = gras_datadesc_struct("s_xbt_peer_t"); + gras_datadesc_struct_append(ddt, "name", + gras_datadesc_by_name("string")); + gras_datadesc_struct_append(ddt, "port", gras_datadesc_by_name("int")); + gras_datadesc_struct_close(ddt); + + ddt = gras_datadesc_ref("xbt_peer_t", ddt); + + /* Dict containing the constant value (for the parsing macro) */ + gras_dd_constants = xbt_dict_new(); -/** - * gras_ddt_new_struct: - * - * Create a new struct and give a pointer to it - */ -gras_error_t -gras_ddt_new_struct(const char *name, - gras_datadesc_type_cb_void_t pre, - gras_datadesc_type_cb_void_t post, - gras_datadesc_type_t **dst) { - - gras_error_t errcode; - gras_datadesc_type_t *res; - - TRY(gras_ddt_new(name,dst)); - res=*dst; - - res->size = 0; - res->alignment = 0; - res->aligned_size = 0; - res->category_code = e_gras_datadesc_type_cat_struct; - TRY(gras_dynar_new(&(res->category.struct_data.fields), - sizeof(gras_dd_cat_field_t*), - &gras_dd_cat_field_free)); - res->pre = pre; - res->post = post; - - return no_error; } /** - * gras_ddt_new_struct_append: + * gras_datadesc_exit: * - * Append a field to the struct - */ -gras_error_t -gras_ddt_new_struct_append(gras_datadesc_type_t *struct_type, - const char *name, - gras_datadesc_type_t *field_type, - gras_datadesc_type_cb_void_t pre, - gras_datadesc_type_cb_void_t post) { - - gras_error_t errcode; - gras_dd_cat_field_t *field; - - gras_assert0(field_type->size >= 0, - "Cannot add a dynamically sized field in a structure"); - - field=malloc(sizeof(gras_dd_cat_field_t)); - if (!field) - RAISE_MALLOC; - - field->name = strdup(name); - field->offset = aligned(struct_type->size, field_type->alignment); - field->code = field_type->code; - field->pre = pre; - field->post = post; - - TRY(gras_dynar_push(struct_type->category.struct_data.fields, field)); - - struct_type->size = field->offset + field_type->size; - struct_type->alignment = max(struct_type->alignment, field_type->alignment); - struct_type->aligned_size = aligned(struct_type->size, struct_type->alignment); - - return no_error; + * Finalize the datadesc module + **/ +void gras_datadesc_exit(void) +{ + XBT_VERB("Exiting DataDesc"); + xbt_set_free(&gras_datadesc_set_local); + xbt_dict_free(&gras_dd_constants); + XBT_DEBUG("Exited DataDesc"); } -/** - * gras_ddt_new_union: - * - * Create a new union and give a pointer to it - */ -gras_error_t -gras_ddt_new_union(const char *name, - gras_datadesc_type_cb_int_t field_count, - gras_datadesc_type_cb_void_t post, - gras_datadesc_type_t **dst) { - - gras_error_t errcode; - gras_datadesc_type_t *res; - - gras_assert0(field_count, - "Attempt to creat an union without field_count function"); - - TRY(gras_ddt_new(name,dst)); - res=*dst; - - res->size = 0; - res->alignment = 0; - res->aligned_size = 0; - res->category_code = e_gras_datadesc_type_cat_union; - TRY(gras_dynar_new(&(res->category.union_data.fields), - sizeof(gras_dd_cat_field_t*), - &gras_dd_cat_field_free)); - res->category.union_data.field_count = field_count; - res->pre = NULL; - res->post = post; - - return no_error; +/** This is mainly to debug */ +const char *gras_datadesc_get_name(gras_datadesc_type_t ddt) +{ + return ddt ? (const char *) ddt->name : "(null)"; } -/** - * gras_ddt_new_union_append: - * - * Append a field to the union - */ -gras_error_t -gras_ddt_new_union_append(gras_datadesc_type_t *union_type, - const char *name, - gras_datadesc_type_t *field_type, - gras_datadesc_type_cb_void_t pre, - gras_datadesc_type_cb_void_t post) { - - gras_error_t errcode; - gras_dd_cat_field_t *field; - - gras_assert0(field_type->size >= 0, - "Cannot add a dynamically sized field in an union"); - - field=malloc(sizeof(gras_dd_cat_field_t)); - if (!field) - RAISE_MALLOC; - - field->name = strdup(name); - field->offset = 0; /* that's the purpose of union ;) */ - field->code = field_type->code; - field->pre = pre; - field->post = post; - - TRY(gras_dynar_push(union_type->category.union_data.fields, field)); - - union_type->size = max(union_type->size, field_type->size); - union_type->alignment = max(union_type->alignment, field_type->alignment); - union_type->aligned_size = aligned(union_type->size, union_type->alignment); - - return no_error; +/** This is mainly to debug */ +int gras_datadesc_get_id(gras_datadesc_type_t ddt) +{ + return ddt->code; } /** - * gras_ddt_new_ref: + * gras_datadesc_size: + * + * Returns the size occuped by data of this type (on the current arch). * - * Create a new ref and give a pointer to it */ -gras_error_t -gras_ddt_new_ref(const char *name, - gras_datadesc_type_t *referenced_type, - gras_datadesc_type_cb_int_t discriminant, - gras_datadesc_type_cb_void_t post, - gras_datadesc_type_t **dst) { - - gras_error_t errcode; - gras_datadesc_type_t *res; - - gras_assert0(discriminant || referenced_type, - "Attempt to create a generic reference without discriminant"); - - TRY(gras_ddt_new(name,dst)); - res=*dst; - - /* FIXME: Size from bootstraping */ - res->size = 0; - res->alignment = 0; - res->aligned_size = 0; - res->category_code = e_gras_datadesc_type_cat_ref; - - res->category.ref_data.code = referenced_type ? referenced_type->code : -1; - res->category.ref_data.discriminant = discriminant; - res->pre = NULL; - res->post = post; - - return no_error; +int gras_datadesc_size(gras_datadesc_type_t type) +{ + return type ? type->size[GRAS_THISARCH] : 0; } /** - * gras_ddt_new_array: + * gras_datadesc_type_dump: * - * Create a new array and give a pointer to it + * For debugging purpose */ -gras_error_t -gras_ddt_new_array(const char *name, - gras_datadesc_type_t *element_type, - long int fixed_size, - gras_datadesc_type_cb_int_t dynamic_size, - gras_datadesc_type_cb_void_t post, - gras_datadesc_type_t **dst) { - - gras_error_t errcode; - gras_datadesc_type_t *res; - - gras_assert0(dynamic_size || fixed_size>0, - "Attempt to create a dynamic array without size discriminant"); - - TRY(gras_ddt_new(name,dst)); - res=*dst; - - if (fixed_size <= 0) { - res->size = fixed_size; - } else { - res->size = fixed_size * element_type->aligned_size; +void gras_datadesc_type_dump(const gras_datadesc_type_t ddt) +{ + unsigned int cpt; + + printf("DataDesc dump:"); + if (!ddt) { + printf("(null)\n"); + return; } - res->alignment = element_type->alignment; - res->aligned_size = fixed_size; /*FIXME: That was so in GS, but looks stupid*/ - res->category_code = e_gras_datadesc_type_cat_array; - - res->category.array_data.code = element_type->code; - res->category.array_data.fixed_size = fixed_size; - res->category.array_data.dynamic_size = dynamic_size; - - res->pre = NULL; - res->post = post; - - return no_error; -} - -/*** - *** BOOTSTRAPING FUNCTIONS: known within GRAS only - ***/ - -/*** - *** DECLARATION FUNCTIONS: public functions - ***/ -gras_error_t -gras_datadesc_declare_struct_cb(const char *name, - gras_datadesc_type_cb_void_t pre, - gras_datadesc_type_cb_void_t post, - long int *code) { - gras_error_t errcode; - gras_datadesc_type_t *type; - TRY(gras_ddt_new_struct(name, pre, post, &type)); - TRY(gras_ddt_register(gras_datadesc_set_local, type)); - *code = type->code; - return no_error; -} - -gras_error_t -gras_datadesc_declare_struct_add_name_cb(long int struct_code, - const char *field_name, - const char *field_type_name, - gras_datadesc_type_cb_void_t pre_cb, - gras_datadesc_type_cb_void_t post_cb) { - - gras_error_t errcode; - gras_datadesc_type_t *struct_type; - gras_datadesc_type_t *field_type; - - TRY(gras_set_get_by_id(gras_datadesc_set_local,struct_code, - (gras_set_elm_t**)struct_type)); - TRY(gras_set_get_by_name(gras_datadesc_set_local,field_type_name, - (gras_set_elm_t**)field_type)); - - TRY(gras_ddt_new_struct_append(struct_type, - field_name, field_type, - pre_cb, post_cb)); - - return no_error; -} -gras_error_t -gras_datadesc_declare_struct_add_code_cb(long int struct_code, - const char *field_name, - long int field_code, - gras_datadesc_type_cb_void_t pre_cb, - gras_datadesc_type_cb_void_t post_cb) { - gras_error_t errcode; - gras_datadesc_type_t *struct_type; - gras_datadesc_type_t *field_type; - - TRY(gras_set_get_by_id(gras_datadesc_set_local,struct_code, - (gras_set_elm_t**)struct_type)); - TRY(gras_set_get_by_id(gras_datadesc_set_local,field_code, - (gras_set_elm_t**)field_type)); - - TRY(gras_ddt_new_struct_append(struct_type, - field_name, field_type, - pre_cb, post_cb)); - - return no_error; -} - -gras_error_t -gras_datadesc_declare_union_cb(const char *name, - gras_datadesc_type_cb_int_t field_count, - gras_datadesc_type_cb_void_t post, - long int *code) { - gras_error_t errcode; - gras_datadesc_type_t *type; - TRY(gras_ddt_new_union(name, field_count, post, &type)); - TRY(gras_ddt_register(gras_datadesc_set_local, type)); - *code = type->code; - return no_error; -} - -gras_error_t -gras_datadesc_declare_union_add_name_cb(long int union_code, - const char *field_name, - const char *field_type_name, - gras_datadesc_type_cb_void_t pre_cb, - gras_datadesc_type_cb_void_t post_cb) { - gras_error_t errcode; - gras_datadesc_type_t *union_type; - gras_datadesc_type_t *field_type; - - TRY(gras_set_get_by_id(gras_datadesc_set_local,union_code, - (gras_set_elm_t**)union_type)); - TRY(gras_set_get_by_name(gras_datadesc_set_local,field_type_name, - (gras_set_elm_t**)field_type)); - - TRY(gras_ddt_new_union_append(union_type, - field_name, field_type, - pre_cb, post_cb)); - - return no_error; -} -gras_error_t -gras_datadesc_declare_union_add_code_cb(long int union_code, - const char *field_name, - long int field_code, - gras_datadesc_type_cb_void_t pre_cb, - gras_datadesc_type_cb_void_t post_cb) { - gras_error_t errcode; - gras_datadesc_type_t *union_type; - gras_datadesc_type_t *field_type; - - TRY(gras_set_get_by_id(gras_datadesc_set_local,union_code, - (gras_set_elm_t**)union_type)); - TRY(gras_set_get_by_id(gras_datadesc_set_local,field_code, - (gras_set_elm_t**)field_type)); - - TRY(gras_ddt_new_union_append(union_type, - field_name, field_type, - pre_cb, post_cb)); - - return no_error; -} - -gras_error_t -gras_datadesc_declare_ref_cb(const char *name, - gras_datadesc_type_t *referenced_type, - gras_datadesc_type_cb_int_t discriminant, - gras_datadesc_type_cb_void_t post, - long int *code){ - gras_error_t errcode; - gras_datadesc_type_t *type; - TRY(gras_ddt_new_ref(name, referenced_type,discriminant,post, &type)); - TRY(gras_ddt_register(gras_datadesc_set_local, type)); - *code = type->code; - return no_error; -} - -gras_error_t -gras_datadesc_declare_array_cb(const char *name, - gras_datadesc_type_t *element_type, - long int fixed_size, - gras_datadesc_type_cb_int_t dynamic_size, - gras_datadesc_type_cb_void_t post, - long int *code){ - gras_error_t errcode; - gras_datadesc_type_t *type; - TRY(gras_ddt_new_array(name, element_type, fixed_size, dynamic_size, post, &type)); - TRY(gras_ddt_register(gras_datadesc_set_local, type)); - *code = type->code; - return no_error; + printf("%s (ID:%d)\n", ddt->name, ddt->code); + printf(" category: %s\n", gras_datadesc_cat_names[ddt->category_code]); + + printf(" size["); + for (cpt = 0; cpt < gras_arch_count; cpt++) { + printf("%s%s%ld%s", + cpt > 0 ? ", " : "", + cpt == GRAS_THISARCH ? ">" : "", + ddt->size[cpt], cpt == GRAS_THISARCH ? "<" : ""); + } + printf("]\n"); + + printf(" alignment["); + for (cpt = 0; cpt < gras_arch_count; cpt++) { + printf("%s%s%ld%s", + cpt > 0 ? ", " : "", + cpt == GRAS_THISARCH ? ">" : "", + ddt->alignment[cpt], cpt == GRAS_THISARCH ? "<" : ""); + } + printf("]\n"); + + printf(" aligned_size["); + for (cpt = 0; cpt < gras_arch_count; cpt++) { + printf("%s%s%ld%s", + cpt > 0 ? ", " : "", + cpt == GRAS_THISARCH ? ">" : "", + ddt->aligned_size[cpt], cpt == GRAS_THISARCH ? "<" : ""); + } + printf("]\n"); + if (ddt->category_code == e_gras_datadesc_type_cat_struct) { + gras_dd_cat_struct_t struct_data; + gras_dd_cat_field_t field; + + struct_data = ddt->category.struct_data; + xbt_dynar_foreach(struct_data.fields, cpt, field) { + printf(">>> Dump field #%d (%s) (offset=%ld)\n", + cpt, field->name, field->offset[GRAS_THISARCH]); + gras_datadesc_type_dump(field->type); + printf("<<< end dump field #%d (%s)\n", cpt, field->name); + } + } + fflush(stdout); }