From: Philippe E. <ph...@us...> - 2003-06-03 16:19:01
|
Update of /cvsroot/oprofile/oprofile/libdb In directory sc8-pr-cvs1:/tmp/cvs-serv11144/libdb Modified Files: db_insert.c db_manage.c db_test.c odb_hash.h Log Message: error message is now a field of a samples_odb_t Index: db_insert.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/libdb/db_insert.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -p -d -r1.5 -r1.6 --- db_insert.c 31 Mar 2003 16:39:41 -0000 1.5 +++ db_insert.c 3 Jun 2003 16:18:52 -0000 1.6 @@ -14,7 +14,7 @@ #include "odb_hash.h" -int odb_insert(samples_odb_t * hash, odb_key_t key, odb_value_t value, char ** err_msg) +int odb_insert(samples_odb_t * hash, odb_key_t key, odb_value_t value) { size_t index; odb_index_t new_node; @@ -42,7 +42,7 @@ int odb_insert(samples_odb_t * hash, odb * the node_base array, odb_hash_add_node() increase current_size but * odb_travel just ignore node with a zero key so on setting the key * atomically update the node */ - new_node = odb_hash_add_node(hash, err_msg); + new_node = odb_hash_add_node(hash); if (new_node == ODB_NODE_NR_INVALID) { return EXIT_FAILURE; } Index: db_manage.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/libdb/db_manage.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -p -d -r1.6 -r1.7 --- db_manage.c 17 May 2003 18:05:15 -0000 1.6 +++ db_manage.c 3 Jun 2003 16:18:53 -0000 1.7 @@ -56,12 +56,26 @@ static unsigned int tables_size(samples_ } -odb_index_t odb_hash_add_node(samples_odb_t * hash, char ** err_msg) +void odb_set_error(samples_odb_t * hash, char const * err_msg) +{ + if (hash->err_msg) { + fprintf(stderr, "FATAL: odb_set_error() attempt to set error " + "whilst an error already occured\n first error is: %s", + hash->err_msg); + exit(EXIT_FAILURE); + } + + hash->err_msg = err_msg; +} + + +odb_index_t odb_hash_add_node(samples_odb_t * hash) { if (hash->descr->current_size >= hash->descr->size) { unsigned int old_file_size; unsigned int new_file_size; unsigned int pos; + char * err_msg; old_file_size = tables_size(hash, hash->descr->size); @@ -70,9 +84,10 @@ odb_index_t odb_hash_add_node(samples_od new_file_size = tables_size(hash, hash->descr->size); if (ftruncate(hash->fd, new_file_size)) { - asprintf(err_msg, "unable to resize file to %d " + asprintf(&err_msg, "unable to resize file to %d " "length, cause : %s\n", new_file_size, strerror(errno)); + odb_set_error(hash, err_msg); return ODB_NODE_NR_INVALID; } @@ -80,8 +95,9 @@ odb_index_t odb_hash_add_node(samples_od old_file_size, new_file_size, MREMAP_MAYMOVE); if (hash->base_memory == MAP_FAILED) { - asprintf(err_msg, "odb_hash_add_page() mremap failure " - "cause: %s\n", strerror(errno)); + asprintf(&err_msg, "odb_hash_add_page() mremap" + " failure cause: %s\n", strerror(errno)); + odb_set_error(hash, err_msg); return ODB_NODE_NR_INVALID; } @@ -126,16 +142,19 @@ void odb_init(samples_odb_t * hash) { memset(hash, '\0', sizeof(samples_odb_t)); hash->fd = -1; + hash->err_msg = NULL; } /* the default number of page, calculated to fit in 4096 bytes */ #define DEFAULT_NODE_NR(offset_node) 128 int odb_open(samples_odb_t * hash, char const * filename, enum odb_rw rw, - size_t sizeof_header, char ** err_msg) + size_t sizeof_header) { struct stat stat_buf; odb_node_nr_t nr_node; + char * err_msg; + int flags = (rw == ODB_RDWR) ? (O_CREAT | O_RDWR) : O_RDONLY; int mmflags = (rw == ODB_RDWR) ? (PROT_READ | PROT_WRITE) : PROT_READ; @@ -146,14 +165,16 @@ int odb_open(samples_odb_t * hash, char hash->fd = open(filename, flags, 0644); if (hash->fd < 0) { - asprintf(err_msg, "odb_open(): fail to open %s cause: %s\n", + asprintf(&err_msg, "odb_open(): fail to open %s cause: %s\n", filename, strerror(errno)); + odb_set_error(hash, err_msg); return EXIT_FAILURE; } if (fstat(hash->fd, &stat_buf)) { - asprintf(err_msg, "odb_open(): unable to stat %s cause %s\n", + asprintf(&err_msg, "odb_open(): unable to stat %s cause %s\n", filename, strerror(errno)); + odb_set_error(hash, err_msg); return EXIT_FAILURE; } @@ -161,8 +182,9 @@ int odb_open(samples_odb_t * hash, char size_t file_size; if (rw == ODB_RDONLY) { - asprintf(err_msg, "odb_open() %s sample file empty\n", + asprintf(&err_msg, "odb_open() %s sample file empty\n", filename); + odb_set_error(hash, err_msg); return EXIT_FAILURE; } @@ -170,10 +192,11 @@ int odb_open(samples_odb_t * hash, char file_size = tables_size(hash, nr_node); if (ftruncate(hash->fd, file_size)) { - asprintf(err_msg, "odb_open() unable to resize file " + asprintf(&err_msg, "odb_open() unable to resize file " "%s to %ld length, cause : %s\n", filename, (unsigned long)file_size, strerror(errno)); + odb_set_error(hash, err_msg); return EXIT_FAILURE; } } else { @@ -186,8 +209,9 @@ int odb_open(samples_odb_t * hash, char MAP_SHARED, hash->fd, 0); if (hash->base_memory == MAP_FAILED) { - asprintf(err_msg, "odb_open() mmap failure cause: %s\n", + asprintf(&err_msg, "odb_open() mmap failure cause: %s\n", strerror(errno)); + odb_set_error(hash, err_msg); return EXIT_FAILURE; } @@ -200,8 +224,9 @@ int odb_open(samples_odb_t * hash, char } else { /* file already exist, sanity check nr node */ if (nr_node != hash->descr->size) { - asprintf(err_msg, "odb_open(): nr_node != " + asprintf(&err_msg, "odb_open(): nr_node != " "hash->descr->size\n"); + odb_set_error(hash, err_msg); return EXIT_FAILURE; } } @@ -216,6 +241,8 @@ int odb_open(samples_odb_t * hash, char void odb_close(samples_odb_t * hash) { + odb_clear_error(hash); + if (hash->base_memory) { size_t size = tables_size(hash, hash->descr->size); @@ -226,6 +253,15 @@ void odb_close(samples_odb_t * hash) if (hash->fd != -1) { close(hash->fd); hash->fd = -1; + } +} + + +void odb_clear_error(samples_odb_t * hash) +{ + if (hash->err_msg) { + free((char *)hash->err_msg); + hash->err_msg = NULL; } } Index: db_test.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/libdb/db_test.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -p -d -r1.7 -r1.8 --- db_test.c 31 Mar 2003 16:39:41 -0000 1.7 +++ db_test.c 3 Jun 2003 16:18:53 -0000 1.8 @@ -38,21 +38,17 @@ static void speed_test(int nr_item, int double begin, end; samples_odb_t hash; int rc; - char * err_msg; - rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header), - &err_msg); + rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); if (rc != EXIT_SUCCESS) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", hash.err_msg); exit(EXIT_FAILURE); } begin = used_time(); for (i = 0 ; i < nr_item ; ++i) { - rc = odb_insert(&hash, (random() % nr_unique_item) + 1, 1, &err_msg); + rc = odb_insert(&hash, (random() % nr_unique_item) + 1, 1); if (rc != EXIT_SUCCESS) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", hash.err_msg); exit(EXIT_FAILURE); } } @@ -82,23 +78,19 @@ static int test(int nr_item, int nr_uniq samples_odb_t hash; int ret; int rc; - char * err_msg; - rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header), - &err_msg); + rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); if (rc != EXIT_SUCCESS) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", hash.err_msg); exit(EXIT_FAILURE); } for (i = 0 ; i < nr_item ; ++i) { odb_key_t key = (random() % nr_unique_item) + 1; - rc = odb_insert(&hash, key, 1, &err_msg); + rc = odb_insert(&hash, key, 1); if (rc != EXIT_SUCCESS) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", hash.err_msg); exit(EXIT_FAILURE); } } @@ -148,21 +140,17 @@ static int callback_test(int nr_item, in odb_key_t first_key, last_key; int old_nr_error = nr_error; int rc; - char * err_msg; - rc = odb_open(&tree, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header), - &err_msg); + rc = odb_open(&tree, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); if (EXIT_SUCCESS != rc) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", tree.err_msg); exit(EXIT_FAILURE); } for (i = 0 ; i < nr_item ; ++i) { - rc = odb_insert(&tree, (random() % nr_unique_item) + 1, 1, &err_msg); + rc = odb_insert(&tree, (random() % nr_unique_item) + 1, 1); if (rc != EXIT_SUCCESS) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", tree.err_msg); exit(EXIT_FAILURE); } } @@ -206,13 +194,10 @@ static void sanity_check(char const * fi { samples_odb_t hash; int rc; - char * err_msg; - rc = odb_open(&hash, filename, ODB_RDONLY, sizeof(struct opd_header), - &err_msg); + rc = odb_open(&hash, filename, ODB_RDONLY, sizeof(struct opd_header)); if (EXIT_SUCCESS != rc) { - fprintf(stderr, "%s", err_msg); - free(err_msg); + fprintf(stderr, "%s", hash.err_msg); exit(EXIT_FAILURE); } Index: odb_hash.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/libdb/odb_hash.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- odb_hash.h 31 May 2003 18:21:40 -0000 1.2 +++ odb_hash.h 3 Jun 2003 16:18:53 -0000 1.3 @@ -30,7 +30,8 @@ typedef odb_index_t odb_hash_mask_t; * goal is to get a O(1) amortized insert time. bucket factor must be a * power of two. FIXME: see big comment in odb_hash_add_node, you must * re-enable zeroing hash table if BUCKET_FACTOR > 2 (roughly exact, you - * want to read the comment in odb_add_hash_node() if you tune this define) */ + * want to read the comment in odb_add_hash_node() if you tune this define) + */ #define BUCKET_FACTOR 1 /** a db hash node */ @@ -42,7 +43,8 @@ typedef struct { /** the minimal information which must be stored in the file to reload * properly the data base, following this header is the node array then - * the hash table (when growing we avoid to copy node array) */ + * the hash table (when growing we avoid to copy node array) + */ typedef struct { odb_node_nr_t size; /**< in node nr (power of two) */ odb_node_nr_t current_size; /**< nr used node + 1, node 0 unused */ @@ -66,6 +68,9 @@ typedef struct { * the hash table: array of odb_index_t indexing the node array * (descr->size * BUCKET_FACTOR) entries * + * the err_msg field is cleared by odb_clear_error(). This field record + * the first error encountered. It's a fatal error if an error occur and this + * field is non NULL */ typedef struct { odb_node_t * node_base; /**< base memory area of the page */ @@ -76,6 +81,7 @@ typedef struct { unsigned int offset_node; /**< from base_memory to node array */ void * base_memory; /**< base memory of the maped memory */ int fd; /**< mmaped memory file descriptor */ + char const * err_msg; /**< *first* error message */ } samples_odb_t; #ifdef __cplusplus @@ -102,19 +108,22 @@ void odb_init(samples_odb_t * hash); * @param filename the filename where go the maped memory * @param rw \enum ODB_RW if opening for writing, else \enum ODB_RDONLY * @param sizeof_header size of the file header if any - * @param err_msg error message is returned here when error occurs * * The sizeof_header parameter allows the data file to have a header * at the start of the file which is skipped. * odb_open() always preallocate a few number of pages. * returns EXIT_SUCCESS on success, EXIT_FAILURE on failure - * on failure *err_msg contains a pointer to an asprintf-alloced string - * containing an error message. the string should be freed using free() */ - int odb_open(samples_odb_t * hash, char const * filename, enum odb_rw rw, size_t sizeof_header, char ** err_msg); + * on failure hash->err_msg contains a pointer to a malloced string + * containing an error message. + */ +int odb_open(samples_odb_t * hash, char const * filename, enum odb_rw rw, size_t sizeof_header); /** Close the given ODB hash */ void odb_close(samples_odb_t * hash); +/** clear the last occured error */ +void odb_clear_error(samples_odb_t * hash); + /** issue a msync on the used size of the mmaped file */ void odb_sync(samples_odb_t const * hash); @@ -122,9 +131,10 @@ void odb_sync(samples_odb_t const * hash * invalidated by this call ! * returns the index of the created node on success or * ODB_NODE_NR_INVALID on failure - * on failure *err_msg contains a pointer to an asprintf-alloced string - * containing an error message. the string should be freed using free() */ -odb_node_nr_t odb_hash_add_node(samples_odb_t * hash, char ** err_msg); + * on failure hash->err_msg contains a pointer to a malloced string + * containing an error message. + */ +odb_node_nr_t odb_hash_add_node(samples_odb_t * hash); /** "immpossible" node number to indicate an error from odb_hash_add_node() */ #define ODB_NODE_NR_INVALID ((odb_node_nr_t)-1) @@ -147,9 +157,10 @@ void odb_hash_free_stat(odb_hash_stat_t /** insert info at key, if key already exist the info is added to the * existing samples * returns EXIT_SUCCESS on success, EXIT_FAILURE on failure - * on failure *err_msg contains a pointer to an asprintf-alloced string - * containing an error message. the string should be freed using free() */ -int odb_insert(samples_odb_t * hash, odb_key_t key, odb_value_t value, char ** err_msg); + * on failure hash->err_msg contains a pointer to a malloced string + * containing an error message. + */ +int odb_insert(samples_odb_t * hash, odb_key_t key, odb_value_t value); /* odb_travel.c */ /** the call back type to pass to travel() */ @@ -185,9 +196,15 @@ static __inline unsigned int do_hash(sam * so this hash coding use 15 low order bits of eip, then add one hash * bits at each grow. Hash table is stored in files avoiding to rebuild * ing them at profiling re-start so on changing do_hash() change the - * file format */ + * file format + */ return ((value << 0) ^ (value >> 8)) & hash->hash_mask; } + +/** not a part of the public interface: set error message to error. Fatal error + * occur if hash->error_msg != NULL + */ +void odb_set_error(samples_odb_t * hash, char const * err_msg); #ifdef __cplusplus } |