From 443612b53ebd2c5f57bb240f795b48c478f88e0a Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 24 Dec 2024 15:55:25 -0600 Subject: [PATCH 1/8] Add tests for threadsafe 'factory' free list operations Signed-off-by: Quincey Koziol --- test/ttsafe_h5fl.c | 1052 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 830 insertions(+), 222 deletions(-) diff --git a/test/ttsafe_h5fl.c b/test/ttsafe_h5fl.c index 1bfac610578..46007008d2d 100644 --- a/test/ttsafe_h5fl.c +++ b/test/ttsafe_h5fl.c @@ -35,65 +35,65 @@ /* Types of various sizes, for regular free lists */ typedef struct { unsigned char buf[16]; -} test_type_1; +} h5fl_reg_test_type_1; typedef struct { unsigned char buf[64]; -} test_type_2; +} h5fl_reg_test_type_2; typedef struct { unsigned char buf[256]; -} test_type_3; +} h5fl_reg_test_type_3; typedef struct { unsigned char buf[1]; -} test_type_4; +} h5fl_reg_test_type_4; typedef struct { unsigned char buf[2]; -} test_type_5; +} h5fl_reg_test_type_5; typedef struct { unsigned char buf[3]; -} test_type_6; +} h5fl_reg_test_type_6; typedef struct { unsigned char buf[5]; -} test_type_7; +} h5fl_reg_test_type_7; typedef struct { unsigned char buf[8]; -} test_type_8; +} h5fl_reg_test_type_8; typedef struct { unsigned char buf[13]; -} test_type_9; +} h5fl_reg_test_type_9; typedef struct { unsigned char buf[21]; -} test_type_10; +} h5fl_reg_test_type_10; typedef struct { unsigned char buf[34]; -} test_type_11; +} h5fl_reg_test_type_11; typedef struct { unsigned char buf[55]; -} test_type_12; +} h5fl_reg_test_type_12; /* Free lists of the various types */ -H5FL_DEFINE_STATIC(test_type_1); -H5FL_DEFINE_STATIC(test_type_2); -H5FL_DEFINE_STATIC(test_type_3); -H5FL_DEFINE_STATIC(test_type_4); -H5FL_DEFINE_STATIC(test_type_5); -H5FL_DEFINE_STATIC(test_type_6); -H5FL_DEFINE_STATIC(test_type_7); -H5FL_DEFINE_STATIC(test_type_8); -H5FL_DEFINE_STATIC(test_type_9); -H5FL_DEFINE_STATIC(test_type_10); -H5FL_DEFINE_STATIC(test_type_11); -H5FL_DEFINE_STATIC(test_type_12); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_1); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_2); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_3); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_4); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_5); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_6); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_7); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_8); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_9); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_10); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_11); +H5FL_DEFINE_STATIC(h5fl_reg_test_type_12); typedef struct { H5FL_reg_head_t *free_list; @@ -102,113 +102,225 @@ typedef struct { unsigned char *fill2; unsigned char *fill3; void *zero; -} type_info; - -/* Array of all the free lists & info */ -static type_info test_types[] = { - {&H5FL_REG_NAME(test_type_1), sizeof(test_type_1), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_2), sizeof(test_type_2), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_3), sizeof(test_type_3), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_4), sizeof(test_type_4), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_5), sizeof(test_type_5), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_6), sizeof(test_type_6), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_7), sizeof(test_type_7), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_8), sizeof(test_type_8), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_9), sizeof(test_type_9), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_10), sizeof(test_type_10), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_11), sizeof(test_type_11), NULL, NULL, NULL, NULL}, - {&H5FL_REG_NAME(test_type_12), sizeof(test_type_12), NULL, NULL, NULL, NULL}, +} h5fl_reg_type_info; + +typedef struct { + H5FL_fac_head_t *free_list; + size_t elmt_size; + unsigned char *fill1; + unsigned char *fill2; + unsigned char *fill3; + void *zero; +} h5fl_fac_type_info; + +/* Array of all the 'regular' free lists & info */ +static h5fl_reg_type_info h5fl_reg_test_types[] = { + {&H5FL_REG_NAME(h5fl_reg_test_type_1), sizeof(h5fl_reg_test_type_1), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_2), sizeof(h5fl_reg_test_type_2), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_3), sizeof(h5fl_reg_test_type_3), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_4), sizeof(h5fl_reg_test_type_4), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_5), sizeof(h5fl_reg_test_type_5), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_6), sizeof(h5fl_reg_test_type_6), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_7), sizeof(h5fl_reg_test_type_7), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_8), sizeof(h5fl_reg_test_type_8), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_9), sizeof(h5fl_reg_test_type_9), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_10), sizeof(h5fl_reg_test_type_10), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_11), sizeof(h5fl_reg_test_type_11), NULL, NULL, NULL, NULL}, + {&H5FL_REG_NAME(h5fl_reg_test_type_12), sizeof(h5fl_reg_test_type_12), NULL, NULL, NULL, NULL}, }; +/* Array of all the 'factory' free lists & info */ +static h5fl_fac_type_info h5fl_fac_test_types[] = { + {NULL, 16, NULL, NULL, NULL, NULL}, + {NULL, 64, NULL, NULL, NULL, NULL}, + {NULL, 256, NULL, NULL, NULL, NULL}, + {NULL, 1, NULL, NULL, NULL, NULL}, + {NULL, 2, NULL, NULL, NULL, NULL}, + {NULL, 3, NULL, NULL, NULL, NULL}, + {NULL, 5, NULL, NULL, NULL, NULL}, + {NULL, 8, NULL, NULL, NULL, NULL}, + {NULL, 13, NULL, NULL, NULL, NULL}, + {NULL, 21, NULL, NULL, NULL, NULL}, + {NULL, 34, NULL, NULL, NULL, NULL}, + {NULL, 55, NULL, NULL, NULL, NULL}, +}; + +typedef enum { + H5FL_REG_OP_MALLOC, + H5FL_REG_OP_CALLOC, + H5FL_REG_OP_ZERO, + H5FL_REG_OP_FILL1, + H5FL_REG_OP_FILL2, + H5FL_REG_OP_FILL3, + H5FL_REG_OP_FREE, +} h5fl_reg_test_op_code; + typedef enum { - OP_MALLOC, - OP_CALLOC, - OP_ZERO, - OP_FILL1, - OP_FILL2, - OP_FILL3, - OP_FREE, -} test_op_code; + H5FL_FAC_OP_MALLOC, + H5FL_FAC_OP_CALLOC, + H5FL_FAC_OP_ZERO, + H5FL_FAC_OP_FILL1, + H5FL_FAC_OP_FILL2, + H5FL_FAC_OP_FILL3, + H5FL_FAC_OP_FREE, +} h5fl_fac_test_op_code; + +typedef enum { H5FL_REG_ST_UNINIT, H5FL_REG_ST_ZERO, H5FL_REG_ST_FILL1, H5FL_REG_ST_FILL2, H5FL_REG_ST_FILL3 } h5fl_reg_token_state; + +typedef enum { H5FL_FAC_ST_UNINIT, H5FL_FAC_ST_ZERO, H5FL_FAC_ST_FILL1, H5FL_FAC_ST_FILL2, H5FL_FAC_ST_FILL3 } h5fl_fac_token_state; -typedef enum { ST_UNINIT, ST_ZERO, ST_FILL1, ST_FILL2, ST_FILL3 } token_state; +typedef struct { + void *val; + unsigned type_idx; + h5fl_reg_token_state state; +} h5fl_reg_test_token; typedef struct { void *val; unsigned type_idx; - token_state state; -} test_token; + h5fl_fac_token_state state; +} h5fl_fac_test_token; typedef union { unsigned type_idx; - test_token *token; -} test_op_param; + h5fl_reg_test_token *token; +} h5fl_reg_test_op_param; + +typedef union { + unsigned type_idx; + h5fl_fac_test_token *token; +} h5fl_fac_test_op_param; typedef struct { - test_op_code op_code; - test_token *token; - test_op_param param; -} test_op; + h5fl_reg_test_op_code op_code; + h5fl_reg_test_token *token; + h5fl_reg_test_op_param param; +} h5fl_reg_test_op; + +typedef struct { + h5fl_fac_test_op_code op_code; + h5fl_fac_test_token *token; + h5fl_fac_test_op_param param; +} h5fl_fac_test_op; + +typedef struct { + unsigned vec_size; + h5fl_reg_test_op *op_vector; +} h5fl_reg_test_vector; typedef struct { unsigned vec_size; - test_op *op_vector; -} test_vector; + h5fl_fac_test_op *op_vector; +} h5fl_fac_test_vector; typedef struct { unsigned odds; - test_op_code op_code; -} test_op_odds; + h5fl_reg_test_op_code op_code; +} h5fl_reg_test_op_odds; + +typedef struct { + unsigned odds; + h5fl_fac_test_op_code op_code; +} h5fl_fac_test_op_odds; /* Operation odds when token array is not full */ /* (Must sum to 1000 (i.e. 100%) */ -static const test_op_odds all_ops_odds[] = { - {221, OP_MALLOC}, /* 22.1% = OP_MALLOC */ - {221, OP_CALLOC}, /* 22.1% = OP_CALLOC */ - {64, OP_ZERO}, /* 6.4% = OP_ZERO */ - {64, OP_FILL1}, /* 6.4% = OP_FILL1 */ - {64, OP_FILL2}, /* 6.4% = OP_FILL2 */ - {64, OP_FILL3}, /* 6.4% = OP_FILL3 */ - {302, OP_FREE}, /* 30.2% = OP_FREE */ +static const h5fl_reg_test_op_odds h5fl_reg_all_ops_odds[] = { + {221, H5FL_REG_OP_MALLOC}, /* 22.1% = H5FL_REG_OP_MALLOC */ + {221, H5FL_REG_OP_CALLOC}, /* 22.1% = H5FL_REG_OP_CALLOC */ + {64, H5FL_REG_OP_ZERO}, /* 6.4% = H5FL_REG_OP_ZERO */ + {64, H5FL_REG_OP_FILL1}, /* 6.4% = H5FL_REG_OP_FILL1 */ + {64, H5FL_REG_OP_FILL2}, /* 6.4% = H5FL_REG_OP_FILL2 */ + {64, H5FL_REG_OP_FILL3}, /* 6.4% = H5FL_REG_OP_FILL3 */ + {302, H5FL_REG_OP_FREE}, /* 30.2% = H5FL_REG_OP_FREE */ +}; + +/* Operation odds when token array is not full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_fac_test_op_odds h5fl_fac_all_ops_odds[] = { + {221, H5FL_FAC_OP_MALLOC}, /* 22.1% = H5FL_FAC_OP_MALLOC */ + {221, H5FL_FAC_OP_CALLOC}, /* 22.1% = H5FL_FAC_OP_CALLOC */ + {64, H5FL_FAC_OP_ZERO}, /* 6.4% = H5FL_FAC_OP_ZERO */ + {64, H5FL_FAC_OP_FILL1}, /* 6.4% = H5FL_FAC_OP_FILL1 */ + {64, H5FL_FAC_OP_FILL2}, /* 6.4% = H5FL_FAC_OP_FILL2 */ + {64, H5FL_FAC_OP_FILL3}, /* 6.4% = H5FL_FAC_OP_FILL3 */ + {302, H5FL_FAC_OP_FREE}, /* 30.2% = H5FL_FAC_OP_FREE */ }; /* Operation odds when token array is full */ /* (Must sum to 1000 (i.e. 100%) */ -static const test_op_odds full_ops_odds[] = { - {0, OP_MALLOC}, /* 0% = OP_MALLOC */ - {0, OP_CALLOC}, /* 0% = OP_CALLOC */ - {104, OP_ZERO}, /* 10.4% = OP_ZERO */ - {104, OP_FILL1}, /* 10.4% = OP_FILL1 */ - {104, OP_FILL2}, /* 10.4% = OP_FILL2 */ - {104, OP_FILL3}, /* 10.4% = OP_FILL3 */ - {584, OP_FREE}, /* 58.4% = OP_FREE */ +static const h5fl_reg_test_op_odds h5fl_reg_full_ops_odds[] = { + {0, H5FL_REG_OP_MALLOC}, /* 0% = H5FL_REG_OP_MALLOC */ + {0, H5FL_REG_OP_CALLOC}, /* 0% = H5FL_REG_OP_CALLOC */ + {104, H5FL_REG_OP_ZERO}, /* 10.4% = H5FL_REG_OP_ZERO */ + {104, H5FL_REG_OP_FILL1}, /* 10.4% = H5FL_REG_OP_FILL1 */ + {104, H5FL_REG_OP_FILL2}, /* 10.4% = H5FL_REG_OP_FILL2 */ + {104, H5FL_REG_OP_FILL3}, /* 10.4% = H5FL_REG_OP_FILL3 */ + {584, H5FL_REG_OP_FREE}, /* 58.4% = H5FL_REG_OP_FREE */ +}; + +/* Operation odds when token array is full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_fac_test_op_odds h5fl_fac_full_ops_odds[] = { + {0, H5FL_FAC_OP_MALLOC}, /* 0% = H5FL_FAC_OP_MALLOC */ + {0, H5FL_FAC_OP_CALLOC}, /* 0% = H5FL_FAC_OP_CALLOC */ + {104, H5FL_FAC_OP_ZERO}, /* 10.4% = H5FL_FAC_OP_ZERO */ + {104, H5FL_FAC_OP_FILL1}, /* 10.4% = H5FL_FAC_OP_FILL1 */ + {104, H5FL_FAC_OP_FILL2}, /* 10.4% = H5FL_FAC_OP_FILL2 */ + {104, H5FL_FAC_OP_FILL3}, /* 10.4% = H5FL_FAC_OP_FILL3 */ + {584, H5FL_FAC_OP_FREE}, /* 58.4% = H5FL_FAC_OP_FREE */ +}; + +/* Operation odds when vector is nearly full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_reg_test_op_odds h5fl_reg_vec_almost_full_ops_odds[] = { + {0, H5FL_REG_OP_MALLOC}, /* 0% = H5FL_REG_OP_MALLOC */ + {0, H5FL_REG_OP_CALLOC}, /* 0% = H5FL_REG_OP_CALLOC */ + {250, H5FL_REG_OP_ZERO}, /* 25% = H5FL_REG_OP_ZERO */ + {250, H5FL_REG_OP_FILL1}, /* 25% = H5FL_REG_OP_FILL1 */ + {250, H5FL_REG_OP_FILL2}, /* 25% = H5FL_REG_OP_FILL2 */ + {250, H5FL_REG_OP_FILL3}, /* 25% = H5FL_REG_OP_FILL3 */ + {0, H5FL_REG_OP_FREE}, /* 0% = H5FL_REG_OP_FREE */ }; /* Operation odds when vector is nearly full */ /* (Must sum to 1000 (i.e. 100%) */ -static const test_op_odds vec_almost_full_ops_odds[] = { - {0, OP_MALLOC}, /* 0% = OP_MALLOC */ - {0, OP_CALLOC}, /* 0% = OP_CALLOC */ - {250, OP_ZERO}, /* 25% = OP_ZERO */ - {250, OP_FILL1}, /* 25% = OP_FILL1 */ - {250, OP_FILL2}, /* 25% = OP_FILL2 */ - {250, OP_FILL3}, /* 25% = OP_FILL3 */ - {0, OP_FREE}, /* 0% = OP_FREE */ +static const h5fl_fac_test_op_odds h5fl_fac_vec_almost_full_ops_odds[] = { + {0, H5FL_FAC_OP_MALLOC}, /* 0% = H5FL_FAC_OP_MALLOC */ + {0, H5FL_FAC_OP_CALLOC}, /* 0% = H5FL_FAC_OP_CALLOC */ + {250, H5FL_FAC_OP_ZERO}, /* 25% = H5FL_FAC_OP_ZERO */ + {250, H5FL_FAC_OP_FILL1}, /* 25% = H5FL_FAC_OP_FILL1 */ + {250, H5FL_FAC_OP_FILL2}, /* 25% = H5FL_FAC_OP_FILL2 */ + {250, H5FL_FAC_OP_FILL3}, /* 25% = H5FL_FAC_OP_FILL3 */ + {0, H5FL_FAC_OP_FREE}, /* 0% = H5FL_FAC_OP_FREE */ }; /* Operation odds when token array is empty */ /* (Must sum to 1000 (i.e. 100%) */ -static const test_op_odds empty_ops_odds[] = { - {500, OP_MALLOC}, /* 50% = OP_MALLOC */ - {500, OP_CALLOC}, /* 50% = OP_CALLOC */ - {0, OP_ZERO}, /* 0% = OP_ZERO */ - {0, OP_FILL1}, /* 0% = OP_FILL1 */ - {0, OP_FILL2}, /* 0% = OP_FILL2 */ - {0, OP_FILL3}, /* 0% = OP_FILL3 */ - {0, OP_FREE}, /* 0% = OP_FREE */ +static const h5fl_reg_test_op_odds h5fl_reg_empty_ops_odds[] = { + {500, H5FL_REG_OP_MALLOC}, /* 50% = H5FL_REG_OP_MALLOC */ + {500, H5FL_REG_OP_CALLOC}, /* 50% = H5FL_REG_OP_CALLOC */ + {0, H5FL_REG_OP_ZERO}, /* 0% = H5FL_REG_OP_ZERO */ + {0, H5FL_REG_OP_FILL1}, /* 0% = H5FL_REG_OP_FILL1 */ + {0, H5FL_REG_OP_FILL2}, /* 0% = H5FL_REG_OP_FILL2 */ + {0, H5FL_REG_OP_FILL3}, /* 0% = H5FL_REG_OP_FILL3 */ + {0, H5FL_REG_OP_FREE}, /* 0% = H5FL_REG_OP_FREE */ +}; + +/* Operation odds when token array is empty */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_fac_test_op_odds h5fl_fac_empty_ops_odds[] = { + {500, H5FL_FAC_OP_MALLOC}, /* 50% = H5FL_FAC_OP_MALLOC */ + {500, H5FL_FAC_OP_CALLOC}, /* 50% = H5FL_FAC_OP_CALLOC */ + {0, H5FL_FAC_OP_ZERO}, /* 0% = H5FL_FAC_OP_ZERO */ + {0, H5FL_FAC_OP_FILL1}, /* 0% = H5FL_FAC_OP_FILL1 */ + {0, H5FL_FAC_OP_FILL2}, /* 0% = H5FL_FAC_OP_FILL2 */ + {0, H5FL_FAC_OP_FILL3}, /* 0% = H5FL_FAC_OP_FILL3 */ + {0, H5FL_FAC_OP_FREE}, /* 0% = H5FL_FAC_OP_FREE */ }; static unsigned -get_new_token(test_token *tokens, unsigned *next_token) +get_new_h5fl_reg_token(h5fl_reg_test_token *tokens, unsigned *next_token) { unsigned curr_pos = *next_token; unsigned start_pos = curr_pos; @@ -227,8 +339,44 @@ get_new_token(test_token *tokens, unsigned *next_token) abort(); } -static test_op_code -get_new_op(const test_op_odds *op_odds) +static unsigned +get_new_h5fl_fac_token(h5fl_fac_test_token *tokens, unsigned *next_token) +{ + unsigned curr_pos = *next_token; + unsigned start_pos = curr_pos; + + do { + /* Check for empty position */ + if (NULL == tokens[curr_pos].val) { + *next_token = (curr_pos + 1) % MAX_TOKENS; + return curr_pos; + } + + curr_pos = (curr_pos + 1) % MAX_TOKENS; + } while (curr_pos != start_pos); + + assert(curr_pos == start_pos && "Can't find empty position for new token"); + abort(); +} + +static h5fl_reg_test_op_code +get_new_h5fl_reg_op(const h5fl_reg_test_op_odds *op_odds) +{ + unsigned idx; + unsigned rng; + + idx = 0; + rng = (unsigned)h5_local_rand() % 1000; + while (0 == op_odds[idx].odds || rng > op_odds[idx].odds) { + rng -= op_odds[idx].odds; + idx++; + } + + return op_odds[idx].op_code; +} + +static h5fl_fac_test_op_code +get_new_h5fl_fac_op(const h5fl_fac_test_op_odds *op_odds) { unsigned idx; unsigned rng; @@ -244,7 +392,26 @@ get_new_op(const test_op_odds *op_odds) } static unsigned -get_active_token(test_token *tokens, unsigned num_possible_tokens) +get_active_h5fl_reg_token(h5fl_reg_test_token *tokens, unsigned num_possible_tokens) +{ + unsigned curr_pos; + unsigned start_pos; + + start_pos = curr_pos = (unsigned)h5_local_rand() % num_possible_tokens; + do { + /* Check for active position */ + if (NULL != tokens[curr_pos].val) + return curr_pos; + + curr_pos = (curr_pos + 1) % num_possible_tokens; + } while (curr_pos != start_pos); + + assert(curr_pos == start_pos && "Can't find active token"); + abort(); +} + +static unsigned +get_active_h5fl_fac_token(h5fl_fac_test_token *tokens, unsigned num_possible_tokens) { unsigned curr_pos; unsigned start_pos; @@ -264,53 +431,113 @@ get_active_token(test_token *tokens, unsigned num_possible_tokens) #if 0 static void -print_h5fl_reg_vector(test_vector *vector, test_token *tokens) +print_h5fl_reg_vector(h5fl_reg_test_vector *vector, h5fl_reg_test_token *tokens) { unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ /* Print test vector */ for (unsigned u = 0; u < vector->vec_size; u++) { switch (vector->op_vector[u].op_code) { - case OP_MALLOC: - fprintf(stderr, "%04u (%u): OP_MALLOC - token: %p, type_idx = %u\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].param.type_idx); + case H5FL_REG_OP_MALLOC: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_MALLOC - token: %p, type_idx = %u\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].param.type_idx); vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->state = ST_UNINIT; + vector->op_vector[u].token->state = H5FL_REG_ST_UNINIT; /* Increment # of active tokens */ num_active_tokens++; break; - case OP_CALLOC: - fprintf(stderr, "%04u (%u): OP_CALLOC - token: %p, type_idx = %u\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].param.type_idx); + case H5FL_REG_OP_CALLOC: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_CALLOC - token: %p, type_idx = %u\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].param.type_idx); vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->state = ST_ZERO; + vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; /* Increment # of active tokens */ num_active_tokens++; break; - case OP_ZERO: - fprintf(stderr, "%04u (%u): OP_ZERO - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); - vector->op_vector[u].token->state = ST_ZERO; + case H5FL_REG_OP_ZERO: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_ZERO - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; break; - case OP_FILL1: - fprintf(stderr, "%04u (%u): OP_FILL1 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); - vector->op_vector[u].token->state = ST_FILL1; + case H5FL_REG_OP_FILL1: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_FILL1 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL1; break; - case OP_FILL2: - fprintf(stderr, "%04u (%u): OP_FILL2 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); - vector->op_vector[u].token->state = ST_FILL2; + case H5FL_REG_OP_FILL2: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_FILL2 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL2; break; - case OP_FILL3: - fprintf(stderr, "%04u (%u): OP_FILL3 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); - vector->op_vector[u].token->state = ST_FILL3; + case H5FL_REG_OP_FILL3: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_FILL3 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL3; break; - case OP_FREE: - fprintf(stderr, "%04u (%u): OP_FREE - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + case H5FL_REG_OP_FREE: + fprintf(stderr, "%04u (%u): H5FL_REG_OP_FREE - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + + /* Decrement # of active tokens */ + num_active_tokens--; + break; + + default: + assert (0 && "Invalid op code"); + abort(); + } + } +} + +static void +print_h5fl_fac_vector(h5fl_fac_test_vector *vector, h5fl_fac_test_token *tokens) +{ + unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ + + /* Print test vector */ + for (unsigned u = 0; u < vector->vec_size; u++) { + switch (vector->op_vector[u].op_code) { + case H5FL_FAC_OP_MALLOC: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_MALLOC - token: %p, type_idx = %u\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].param.type_idx); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->state = H5FL_FAC_ST_UNINIT; + + /* Increment # of active tokens */ + num_active_tokens++; + break; + + case H5FL_FAC_OP_CALLOC: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_CALLOC - token: %p, type_idx = %u\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].param.type_idx); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->state = H5FL_FAC_ST_ZERO; + + /* Increment # of active tokens */ + num_active_tokens++; + break; + + case H5FL_FAC_OP_ZERO: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_ZERO - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_FAC_ST_ZERO; + break; + + case H5FL_FAC_OP_FILL1: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_FILL1 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL1; + break; + + case H5FL_FAC_OP_FILL2: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_FILL2 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL2; + break; + + case H5FL_FAC_OP_FILL3: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_FILL3 - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL3; + break; + + case H5FL_FAC_OP_FREE: + fprintf(stderr, "%04u (%u): H5FL_FAC_OP_FREE - token: %p (type_idx: %u, state: %u)\n", u, num_active_tokens, (void *)vector->op_vector[u].token, vector->op_vector[u].token->type_idx, vector->op_vector[u].token->state); /* Decrement # of active tokens */ num_active_tokens--; @@ -325,7 +552,7 @@ print_h5fl_reg_vector(test_vector *vector, test_token *tokens) #endif static void -init_h5fl_reg_vector(unsigned vec_size, test_vector *vector, unsigned num_tokens, test_token *tokens) +init_h5fl_reg_vector(unsigned vec_size, h5fl_reg_test_vector *vector, unsigned num_tokens, h5fl_reg_test_token *tokens) { unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ unsigned curr_alloc_token; /* Current position for allocating tokens */ @@ -334,30 +561,30 @@ init_h5fl_reg_vector(unsigned vec_size, test_vector *vector, unsigned num_tokens /* Allocate the test vector */ vector->vec_size = vec_size; - vector->op_vector = calloc(vec_size, sizeof(test_op)); + vector->op_vector = calloc(vec_size, sizeof(h5fl_reg_test_op)); CHECK_PTR(vector->op_vector, "calloc"); /* Fiil the test vector, leaving room to free active tokens */ pos = 0; curr_alloc_token = 0; while (pos < (vec_size - num_active_tokens)) { - test_op_code op_code; + h5fl_reg_test_op_code op_code; /* Check for active tokens */ /* (Also must have enough room for both alloc & free operations) */ if (0 == num_active_tokens && pos < (vec_size - 2)) - op_code = get_new_op(empty_ops_odds); + op_code = get_new_h5fl_reg_op(h5fl_reg_empty_ops_odds); else { /* Don't create new tokens when there won't be enough room in the * vector for both the alloc & free operations. */ if (pos > ((vec_size - num_active_tokens) - 2)) - op_code = get_new_op(vec_almost_full_ops_odds); + op_code = get_new_h5fl_reg_op(h5fl_reg_vec_almost_full_ops_odds); /* Don't create new tokens when the token array is full */ else if (num_tokens == num_active_tokens) - op_code = get_new_op(full_ops_odds); + op_code = get_new_h5fl_reg_op(h5fl_reg_full_ops_odds); else - op_code = get_new_op(all_ops_odds); + op_code = get_new_h5fl_reg_op(h5fl_reg_all_ops_odds); } /* Set op code */ @@ -365,15 +592,15 @@ init_h5fl_reg_vector(unsigned vec_size, test_vector *vector, unsigned num_tokens /* Set up specific parameters for each op code */ switch (op_code) { - case OP_MALLOC: - case OP_CALLOC: { + case H5FL_REG_OP_MALLOC: + case H5FL_REG_OP_CALLOC: { unsigned prev_alloc_token = curr_alloc_token; unsigned type_idx; unsigned new_token; /* RNG type to allocate */ - type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(test_types); - new_token = get_new_token(tokens, &curr_alloc_token); + type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_reg_test_types); + new_token = get_new_h5fl_reg_token(tokens, &curr_alloc_token); vector->op_vector[pos].token = &tokens[new_token]; vector->op_vector[pos].param.type_idx = type_idx; @@ -388,17 +615,17 @@ init_h5fl_reg_vector(unsigned vec_size, test_vector *vector, unsigned num_tokens tokens_wrapped = true; } break; - case OP_ZERO: - case OP_FILL1: - case OP_FILL2: - case OP_FILL3: - case OP_FREE: { + case H5FL_REG_OP_ZERO: + case H5FL_REG_OP_FILL1: + case H5FL_REG_OP_FILL2: + case H5FL_REG_OP_FILL3: + case H5FL_REG_OP_FREE: { unsigned token_idx; - token_idx = get_active_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + token_idx = get_active_h5fl_reg_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); vector->op_vector[pos].token = &tokens[token_idx]; - if (OP_FREE == op_code) { + if (H5FL_REG_OP_FREE == op_code) { /* Mark token as free */ tokens[token_idx].val = NULL; @@ -420,9 +647,9 @@ init_h5fl_reg_vector(unsigned vec_size, test_vector *vector, unsigned num_tokens unsigned token_idx; /* Set op code */ - vector->op_vector[pos].op_code = OP_FREE; + vector->op_vector[pos].op_code = H5FL_REG_OP_FREE; - token_idx = get_active_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + token_idx = get_active_h5fl_reg_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); vector->op_vector[pos].token = &tokens[token_idx]; /* Mark token as free */ @@ -438,38 +665,83 @@ init_h5fl_reg_vector(unsigned vec_size, test_vector *vector, unsigned num_tokens } static inline unsigned -validate_token(const test_token *token) +validate_h5fl_reg_token(const h5fl_reg_test_token *token) +{ + int v; + + switch (token->state) { + case H5FL_REG_ST_UNINIT: + break; + + case H5FL_REG_ST_ZERO: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].zero, h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_ZERO"); + if (0 != v) + return (1); + break; + + case H5FL_REG_ST_FILL1: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill1, h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_FILL1"); + if (0 != v) + return (1); + break; + + case H5FL_REG_ST_FILL2: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill2, h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_FILL2"); + if (0 != v) + return (1); + break; + + case H5FL_REG_ST_FILL3: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill3, h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_FILL3"); + if (0 != v) + return (1); + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } + + return (0); +} + +static inline unsigned +validate_h5fl_fac_token(const h5fl_fac_test_token *token) { int v; switch (token->state) { - case ST_UNINIT: + case H5FL_FAC_ST_UNINIT: break; - case ST_ZERO: - v = memcmp(token->val, test_types[token->type_idx].zero, test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "ST_ZERO"); + case H5FL_FAC_ST_ZERO: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].zero, h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_ZERO"); if (0 != v) return (1); break; - case ST_FILL1: - v = memcmp(token->val, test_types[token->type_idx].fill1, test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "ST_FILL1"); + case H5FL_FAC_ST_FILL1: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill1, h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_FILL1"); if (0 != v) return (1); break; - case ST_FILL2: - v = memcmp(token->val, test_types[token->type_idx].fill2, test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "ST_FILL2"); + case H5FL_FAC_ST_FILL2: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill2, h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_FILL2"); if (0 != v) return (1); break; - case ST_FILL3: - v = memcmp(token->val, test_types[token->type_idx].fill3, test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "ST_FILL3"); + case H5FL_FAC_ST_FILL3: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill3, h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_FILL3"); if (0 != v) return (1); break; @@ -482,76 +754,272 @@ validate_token(const test_token *token) return (0); } +static void +init_h5fl_fac_vector(unsigned vec_size, h5fl_fac_test_vector *vector, unsigned num_tokens, h5fl_fac_test_token *tokens) +{ + unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ + unsigned curr_alloc_token; /* Current position for allocating tokens */ + unsigned pos; /* Current position in the test vector */ + bool tokens_wrapped = false; + + /* Allocate the test vector */ + vector->vec_size = vec_size; + vector->op_vector = calloc(vec_size, sizeof(h5fl_fac_test_op)); + CHECK_PTR(vector->op_vector, "calloc"); + + /* Fiil the test vector, leaving room to free active tokens */ + pos = 0; + curr_alloc_token = 0; + while (pos < (vec_size - num_active_tokens)) { + h5fl_fac_test_op_code op_code; + + /* Check for active tokens */ + /* (Also must have enough room for both alloc & free operations) */ + if (0 == num_active_tokens && pos < (vec_size - 2)) + op_code = get_new_h5fl_fac_op(h5fl_fac_empty_ops_odds); + else { + /* Don't create new tokens when there won't be enough room in the + * vector for both the alloc & free operations. + */ + if (pos > ((vec_size - num_active_tokens) - 2)) + op_code = get_new_h5fl_fac_op(h5fl_fac_vec_almost_full_ops_odds); + /* Don't create new tokens when the token array is full */ + else if (num_tokens == num_active_tokens) + op_code = get_new_h5fl_fac_op(h5fl_fac_full_ops_odds); + else + op_code = get_new_h5fl_fac_op(h5fl_fac_all_ops_odds); + } + + /* Set op code */ + vector->op_vector[pos].op_code = op_code; + + /* Set up specific parameters for each op code */ + switch (op_code) { + case H5FL_FAC_OP_MALLOC: + case H5FL_FAC_OP_CALLOC: { + unsigned prev_alloc_token = curr_alloc_token; + unsigned type_idx; + unsigned new_token; + + /* RNG type to allocate */ + type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_fac_test_types); + new_token = get_new_h5fl_fac_token(tokens, &curr_alloc_token); + vector->op_vector[pos].token = &tokens[new_token]; + vector->op_vector[pos].param.type_idx = type_idx; + + /* Mark token as used */ + tokens[new_token].val = (void *)(~(uintptr_t)NULL); + + /* Increment # of active tokens */ + num_active_tokens++; + + /* Check for tokens wrapping */ + if (curr_alloc_token < prev_alloc_token) + tokens_wrapped = true; + } break; + + case H5FL_FAC_OP_ZERO: + case H5FL_FAC_OP_FILL1: + case H5FL_FAC_OP_FILL2: + case H5FL_FAC_OP_FILL3: + case H5FL_FAC_OP_FREE: { + unsigned token_idx; + + token_idx = get_active_h5fl_fac_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + + if (H5FL_FAC_OP_FREE == op_code) { + /* Mark token as free */ + tokens[token_idx].val = NULL; + + /* Decrement # of active tokens */ + num_active_tokens--; + } + } break; + + default: + assert(0 && "Invalid op code"); + abort(); + } + + pos++; + } + + /* Fill remainder of test vector with free operations */ + while (pos < vec_size) { + unsigned token_idx; + + /* Set op code */ + vector->op_vector[pos].op_code = H5FL_FAC_OP_FREE; + + token_idx = get_active_h5fl_fac_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + + /* Mark token as free */ + tokens[token_idx].val = NULL; + + /* Decrement # of active tokens */ + num_active_tokens--; + + pos++; + } + + assert(0 == num_active_tokens); +} + static unsigned -run_h5fl_reg_vector(test_vector *vector) +run_h5fl_reg_vector(h5fl_reg_test_vector *vector) { /* Execute test vector */ for (unsigned u = 0; u < vector->vec_size; u++) { switch (vector->op_vector[u].op_code) { - case OP_MALLOC: + case H5FL_REG_OP_MALLOC: vector->op_vector[u].token->val = - H5FL_reg_malloc(test_types[vector->op_vector[u].param.type_idx].free_list); + H5FL_reg_malloc(h5fl_reg_test_types[vector->op_vector[u].param.type_idx].free_list); CHECK_PTR(vector->op_vector[u].token->val, "H5FL_reg_malloc"); if (NULL == vector->op_vector[u].token->val) return (1); vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->state = ST_UNINIT; + vector->op_vector[u].token->state = H5FL_REG_ST_UNINIT; break; - case OP_CALLOC: + case H5FL_REG_OP_CALLOC: vector->op_vector[u].token->val = - H5FL_reg_calloc(test_types[vector->op_vector[u].param.type_idx].free_list); + H5FL_reg_calloc(h5fl_reg_test_types[vector->op_vector[u].param.type_idx].free_list); CHECK_PTR(vector->op_vector[u].token->val, "H5FL_reg_calloc"); if (NULL == vector->op_vector[u].token->val) return (1); vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->state = ST_ZERO; + vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; break; - case OP_ZERO: - if (ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_token(vector->op_vector[u].token)) + case H5FL_REG_OP_ZERO: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) return (1); memset(vector->op_vector[u].token->val, 0, - test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = ST_ZERO; + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; break; - case OP_FILL1: - if (ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_token(vector->op_vector[u].token)) + case H5FL_REG_OP_FILL1: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) return (1); memcpy(vector->op_vector[u].token->val, - test_types[vector->op_vector[u].token->type_idx].fill1, - test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = ST_FILL1; + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill1, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL1; break; - case OP_FILL2: - if (ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_token(vector->op_vector[u].token)) + case H5FL_REG_OP_FILL2: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) return (1); memcpy(vector->op_vector[u].token->val, - test_types[vector->op_vector[u].token->type_idx].fill2, - test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = ST_FILL2; + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill2, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL2; break; - case OP_FILL3: - if (ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_token(vector->op_vector[u].token)) + case H5FL_REG_OP_FILL3: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) return (1); memcpy(vector->op_vector[u].token->val, - test_types[vector->op_vector[u].token->type_idx].fill3, - test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = ST_FILL3; + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill3, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL3; break; - case OP_FREE: - if (ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_token(vector->op_vector[u].token)) + case H5FL_REG_OP_FREE: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) return (1); - H5FL_reg_free(test_types[vector->op_vector[u].token->type_idx].free_list, + H5FL_reg_free(h5fl_reg_test_types[vector->op_vector[u].token->type_idx].free_list, + vector->op_vector[u].token->val); + vector->op_vector[u].token->val = NULL; + break; + + default: + assert(0 && "Invalid op code"); + abort(); + } + } + + return (0); +} + +static unsigned +run_h5fl_fac_vector(h5fl_fac_test_vector *vector) +{ + /* Execute test vector */ + for (unsigned u = 0; u < vector->vec_size; u++) { + switch (vector->op_vector[u].op_code) { + case H5FL_FAC_OP_MALLOC: + vector->op_vector[u].token->val = + H5FL_fac_malloc(h5fl_fac_test_types[vector->op_vector[u].param.type_idx].free_list); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_fac_malloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->state = H5FL_FAC_ST_UNINIT; + break; + + case H5FL_FAC_OP_CALLOC: + vector->op_vector[u].token->val = + H5FL_fac_calloc(h5fl_fac_test_types[vector->op_vector[u].param.type_idx].free_list); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_fac_calloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->state = H5FL_FAC_ST_ZERO; + break; + + case H5FL_FAC_OP_ZERO: + if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) + return (1); + memset(vector->op_vector[u].token->val, 0, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_ZERO; + break; + + case H5FL_FAC_OP_FILL1: + if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) + return (1); + memcpy(vector->op_vector[u].token->val, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill1, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL1; + break; + + case H5FL_FAC_OP_FILL2: + if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) + return (1); + memcpy(vector->op_vector[u].token->val, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill2, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL2; + break; + + case H5FL_FAC_OP_FILL3: + if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) + return (1); + memcpy(vector->op_vector[u].token->val, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill3, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL3; + break; + + case H5FL_FAC_OP_FREE: + if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) + return (1); + H5FL_fac_free(h5fl_fac_test_types[vector->op_vector[u].token->type_idx].free_list, vector->op_vector[u].token->val); vector->op_vector[u].token->val = NULL; break; @@ -566,9 +1034,9 @@ run_h5fl_reg_vector(test_vector *vector) } static H5TS_THREAD_RETURN_TYPE -test_h5fl_reg(void *_vectors) +thread_h5fl_reg(void *_vectors) { - test_vector *vectors = (test_vector *)_vectors; + h5fl_reg_test_vector *vectors = (h5fl_reg_test_vector *)_vectors; unsigned errors = 0; H5TS_THREAD_RETURN_TYPE ret_value = (H5TS_THREAD_RETURN_TYPE)0; @@ -586,50 +1054,52 @@ test_h5fl_reg(void *_vectors) return ret_value; } -static test_vector *h5fl_reg_vectors[NUM_THREADS]; /* 'regular' H5FL test vectors */ +/* 'regular' H5FL test vectors */ +static h5fl_reg_test_vector *h5fl_reg_vectors[NUM_THREADS]; -/* - ********************************************************************** - * Test H5FL package - ********************************************************************** - */ -void -tts_h5fl(const void H5_ATTR_UNUSED *params) +static void +test_h5fl_reg(void) { - test_token *tokens[NUM_THREADS]; /* Test tokens */ + h5fl_reg_test_token *tokens[NUM_THREADS]; /* Test tokens */ H5TS_thread_t threads[NUM_THREADS]; herr_t result; - /* Set up local RNG */ - h5_setup_local_rand("tts_h5fl", 0); + + /* Output message about test being performed */ + MESSAGE(7, ("Testing 'regular' H5FL operations\n")); /* Initialize the zero values for each type */ - for (unsigned u = 0; u < (unsigned)NELMTS(test_types); u++) - test_types[u].zero = calloc(1, test_types[u].elmt_size); + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_reg_test_types); u++) { + h5fl_reg_test_types[u].zero = calloc(1, h5fl_reg_test_types[u].elmt_size); + CHECK_PTR(h5fl_reg_test_types[u].zero, "calloc"); + } /* Initialize the fill values for each type to RNG values */ - for (unsigned u = 0; u < (unsigned)NELMTS(test_types); u++) { - test_types[u].fill1 = malloc(test_types[u].elmt_size); - for (unsigned v = 0; v < test_types[u].elmt_size; v++) - test_types[u].fill1[v] = (unsigned char)h5_local_rand(); - - test_types[u].fill2 = malloc(test_types[u].elmt_size); - for (unsigned v = 0; v < test_types[u].elmt_size; v++) - test_types[u].fill2[v] = (unsigned char)h5_local_rand(); - - test_types[u].fill3 = malloc(test_types[u].elmt_size); - for (unsigned v = 0; v < test_types[u].elmt_size; v++) - test_types[u].fill3[v] = (unsigned char)h5_local_rand(); + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_reg_test_types); u++) { + h5fl_reg_test_types[u].fill1 = malloc(h5fl_reg_test_types[u].elmt_size); + CHECK_PTR(h5fl_reg_test_types[u].fill1, "malloc"); + for (unsigned v = 0; v < h5fl_reg_test_types[u].elmt_size; v++) + h5fl_reg_test_types[u].fill1[v] = (unsigned char)h5_local_rand(); + + h5fl_reg_test_types[u].fill2 = malloc(h5fl_reg_test_types[u].elmt_size); + CHECK_PTR(h5fl_reg_test_types[u].fill2, "malloc"); + for (unsigned v = 0; v < h5fl_reg_test_types[u].elmt_size; v++) + h5fl_reg_test_types[u].fill2[v] = (unsigned char)h5_local_rand(); + + h5fl_reg_test_types[u].fill3 = malloc(h5fl_reg_test_types[u].elmt_size); + CHECK_PTR(h5fl_reg_test_types[u].fill3, "malloc"); + for (unsigned v = 0; v < h5fl_reg_test_types[u].elmt_size; v++) + h5fl_reg_test_types[u].fill3[v] = (unsigned char)h5_local_rand(); } - /* Initialize the fill values for each type to RNG values */ + /* Initialize the test vectors */ for (unsigned u = 0; u < NUM_THREADS; u++) { /* Allocate the test tokens */ - tokens[u] = calloc(MAX_TOKENS, sizeof(test_token)); + tokens[u] = calloc(MAX_TOKENS, sizeof(h5fl_reg_test_token)); CHECK_PTR(tokens[u], "calloc"); /* Initialize the test vectors */ - h5fl_reg_vectors[u] = calloc(NUM_VECTORS, sizeof(test_vector)); + h5fl_reg_vectors[u] = calloc(NUM_VECTORS, sizeof(h5fl_reg_test_vector)); CHECK_PTR(h5fl_reg_vectors[u], "calloc"); for (unsigned v = 0; v < NUM_VECTORS; v++) @@ -638,7 +1108,7 @@ tts_h5fl(const void H5_ATTR_UNUSED *params) /* Create threads and have them execute the vector */ for (unsigned u = 0; u < NUM_THREADS; u++) { - result = H5TS_thread_create(&threads[u], test_h5fl_reg, h5fl_reg_vectors[u]); + result = H5TS_thread_create(&threads[u], thread_h5fl_reg, h5fl_reg_vectors[u]); CHECK_I(result, "H5TS_thread_create"); } @@ -663,13 +1133,151 @@ tts_h5fl(const void H5_ATTR_UNUSED *params) } /* Free the zero fill values for each type */ - for (unsigned u = 0; u < (unsigned)NELMTS(test_types); u++) { - free(test_types[u].zero); - free(test_types[u].fill1); - free(test_types[u].fill2); - free(test_types[u].fill3); + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_reg_test_types); u++) { + free(h5fl_reg_test_types[u].zero); + free(h5fl_reg_test_types[u].fill1); + free(h5fl_reg_test_types[u].fill2); + free(h5fl_reg_test_types[u].fill3); + } +} + +static H5TS_THREAD_RETURN_TYPE +thread_h5fl_fac(void *_vectors) +{ + h5fl_fac_test_vector *vectors = (h5fl_fac_test_vector *)_vectors; + unsigned errors = 0; + H5TS_THREAD_RETURN_TYPE ret_value = (H5TS_THREAD_RETURN_TYPE)0; + + /* Randomly run a number of vectors */ + for (unsigned u = 0; u < NUM_ITERS_PER_THREAD; u++) { + unsigned rng = (unsigned)h5_local_rand() % NUM_VECTORS; + + /* Run the test vector */ + errors += run_h5fl_fac_vector(&vectors[rng]); + } + + if (errors > 0) + ret_value = (H5TS_THREAD_RETURN_TYPE)1; + + return ret_value; +} + +/* 'factory' H5FL test vectors */ +static h5fl_fac_test_vector *h5fl_fac_vectors[NUM_THREADS]; + +static void +test_h5fl_fac(void) +{ + h5fl_fac_test_token *tokens[NUM_THREADS]; /* Test tokens */ + H5TS_thread_t threads[NUM_THREADS]; + herr_t result; + + + /* Output message about test being performed */ + MESSAGE(7, ("Testing 'factory' H5FL operations\n")); + + /* Initialize the free list factory for each block size */ + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_fac_test_types); u++) { + h5fl_fac_test_types[u].free_list = H5FL_fac_init(h5fl_fac_test_types[u].elmt_size); + CHECK_PTR(h5fl_fac_test_types[u].free_list, "H5FL_fac_init"); + } + + /* Initialize the zero values for each type */ + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_fac_test_types); u++) { + h5fl_fac_test_types[u].zero = calloc(1, h5fl_fac_test_types[u].elmt_size); + CHECK_PTR(h5fl_fac_test_types[u].zero, "calloc"); + } + + /* Initialize the fill values for each type to RNG values */ + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_fac_test_types); u++) { + h5fl_fac_test_types[u].fill1 = malloc(h5fl_fac_test_types[u].elmt_size); + CHECK_PTR(h5fl_fac_test_types[u].fill1, "malloc"); + for (unsigned v = 0; v < h5fl_fac_test_types[u].elmt_size; v++) + h5fl_fac_test_types[u].fill1[v] = (unsigned char)h5_local_rand(); + + h5fl_fac_test_types[u].fill2 = malloc(h5fl_fac_test_types[u].elmt_size); + CHECK_PTR(h5fl_fac_test_types[u].fill2, "malloc"); + for (unsigned v = 0; v < h5fl_fac_test_types[u].elmt_size; v++) + h5fl_fac_test_types[u].fill2[v] = (unsigned char)h5_local_rand(); + + h5fl_fac_test_types[u].fill3 = malloc(h5fl_fac_test_types[u].elmt_size); + CHECK_PTR(h5fl_fac_test_types[u].fill3, "malloc"); + for (unsigned v = 0; v < h5fl_fac_test_types[u].elmt_size; v++) + h5fl_fac_test_types[u].fill3[v] = (unsigned char)h5_local_rand(); + } + + /* Initialize the test vectors */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + /* Allocate the test tokens */ + tokens[u] = calloc(MAX_TOKENS, sizeof(h5fl_fac_test_token)); + CHECK_PTR(tokens[u], "calloc"); + + /* Initialize the test vectors */ + h5fl_fac_vectors[u] = calloc(NUM_VECTORS, sizeof(h5fl_fac_test_vector)); + CHECK_PTR(h5fl_fac_vectors[u], "calloc"); + + for (unsigned v = 0; v < NUM_VECTORS; v++) + init_h5fl_fac_vector(NUM_TEST_OPS, &h5fl_fac_vectors[u][v], MAX_TOKENS, tokens[u]); + } + + /* Create threads and have them execute the vector */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + result = H5TS_thread_create(&threads[u], thread_h5fl_fac, h5fl_fac_vectors[u]); + CHECK_I(result, "H5TS_thread_create"); + } + + /* Wait for all threads */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + H5TS_THREAD_RETURN_TYPE thread_ret = (H5TS_THREAD_RETURN_TYPE)0; + + /* Join thread */ + result = H5TS_thread_join(threads[u], &thread_ret); + CHECK_I(result, "H5TS_thread_join"); + + /* Verify no errors from thread */ + VERIFY(thread_ret, (H5TS_THREAD_RETURN_TYPE)0, "error in thread"); + } + + /* Free test vectors & tokens */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + free(tokens[u]); + for (unsigned v = 0; v < NUM_VECTORS; v++) + free(h5fl_fac_vectors[u][v].op_vector); + free(h5fl_fac_vectors[u]); + } + + /* Release the free list factory for each block size */ + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_fac_test_types); u++) { + result = H5FL_fac_term(h5fl_fac_test_types[u].free_list); + CHECK_I(result, "H5FL_fac_term"); + } + + /* Free the zero fill values for each type */ + for (unsigned u = 0; u < (unsigned)NELMTS(h5fl_fac_test_types); u++) { + free(h5fl_fac_test_types[u].zero); + free(h5fl_fac_test_types[u].fill1); + free(h5fl_fac_test_types[u].fill2); + free(h5fl_fac_test_types[u].fill3); } +} + +/* + ********************************************************************** + * Test H5FL package + ********************************************************************** + */ +void +tts_h5fl(const void H5_ATTR_UNUSED *params) +{ + /* Output message about test being performed */ + MESSAGE(5, ("Testing threadsafe H5FL operations\n")); + + /* Set up local RNG */ + h5_setup_local_rand("tts_h5fl", 0); + /* Run tests */ + test_h5fl_reg(); + test_h5fl_fac(); } /* end tts_h5fl() */ #endif /*H5_HAVE_THREADS*/ From e672f5c1a95178e4b3afe64ac1cf06291d22d9a1 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 21:57:49 +0000 Subject: [PATCH 2/8] Committing clang-format changes --- test/ttsafe_h5fl.c | 112 +++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 49 deletions(-) diff --git a/test/ttsafe_h5fl.c b/test/ttsafe_h5fl.c index 46007008d2d..a8abd1a52d2 100644 --- a/test/ttsafe_h5fl.c +++ b/test/ttsafe_h5fl.c @@ -131,18 +131,12 @@ static h5fl_reg_type_info h5fl_reg_test_types[] = { /* Array of all the 'factory' free lists & info */ static h5fl_fac_type_info h5fl_fac_test_types[] = { - {NULL, 16, NULL, NULL, NULL, NULL}, - {NULL, 64, NULL, NULL, NULL, NULL}, - {NULL, 256, NULL, NULL, NULL, NULL}, - {NULL, 1, NULL, NULL, NULL, NULL}, - {NULL, 2, NULL, NULL, NULL, NULL}, - {NULL, 3, NULL, NULL, NULL, NULL}, - {NULL, 5, NULL, NULL, NULL, NULL}, - {NULL, 8, NULL, NULL, NULL, NULL}, - {NULL, 13, NULL, NULL, NULL, NULL}, - {NULL, 21, NULL, NULL, NULL, NULL}, - {NULL, 34, NULL, NULL, NULL, NULL}, - {NULL, 55, NULL, NULL, NULL, NULL}, + {NULL, 16, NULL, NULL, NULL, NULL}, {NULL, 64, NULL, NULL, NULL, NULL}, + {NULL, 256, NULL, NULL, NULL, NULL}, {NULL, 1, NULL, NULL, NULL, NULL}, + {NULL, 2, NULL, NULL, NULL, NULL}, {NULL, 3, NULL, NULL, NULL, NULL}, + {NULL, 5, NULL, NULL, NULL, NULL}, {NULL, 8, NULL, NULL, NULL, NULL}, + {NULL, 13, NULL, NULL, NULL, NULL}, {NULL, 21, NULL, NULL, NULL, NULL}, + {NULL, 34, NULL, NULL, NULL, NULL}, {NULL, 55, NULL, NULL, NULL, NULL}, }; typedef enum { @@ -165,29 +159,41 @@ typedef enum { H5FL_FAC_OP_FREE, } h5fl_fac_test_op_code; -typedef enum { H5FL_REG_ST_UNINIT, H5FL_REG_ST_ZERO, H5FL_REG_ST_FILL1, H5FL_REG_ST_FILL2, H5FL_REG_ST_FILL3 } h5fl_reg_token_state; +typedef enum { + H5FL_REG_ST_UNINIT, + H5FL_REG_ST_ZERO, + H5FL_REG_ST_FILL1, + H5FL_REG_ST_FILL2, + H5FL_REG_ST_FILL3 +} h5fl_reg_token_state; -typedef enum { H5FL_FAC_ST_UNINIT, H5FL_FAC_ST_ZERO, H5FL_FAC_ST_FILL1, H5FL_FAC_ST_FILL2, H5FL_FAC_ST_FILL3 } h5fl_fac_token_state; +typedef enum { + H5FL_FAC_ST_UNINIT, + H5FL_FAC_ST_ZERO, + H5FL_FAC_ST_FILL1, + H5FL_FAC_ST_FILL2, + H5FL_FAC_ST_FILL3 +} h5fl_fac_token_state; typedef struct { - void *val; - unsigned type_idx; + void *val; + unsigned type_idx; h5fl_reg_token_state state; } h5fl_reg_test_token; typedef struct { - void *val; - unsigned type_idx; + void *val; + unsigned type_idx; h5fl_fac_token_state state; } h5fl_fac_test_token; typedef union { - unsigned type_idx; + unsigned type_idx; h5fl_reg_test_token *token; } h5fl_reg_test_op_param; typedef union { - unsigned type_idx; + unsigned type_idx; h5fl_fac_test_token *token; } h5fl_fac_test_op_param; @@ -204,22 +210,22 @@ typedef struct { } h5fl_fac_test_op; typedef struct { - unsigned vec_size; + unsigned vec_size; h5fl_reg_test_op *op_vector; } h5fl_reg_test_vector; typedef struct { - unsigned vec_size; + unsigned vec_size; h5fl_fac_test_op *op_vector; } h5fl_fac_test_vector; typedef struct { - unsigned odds; + unsigned odds; h5fl_reg_test_op_code op_code; } h5fl_reg_test_op_odds; typedef struct { - unsigned odds; + unsigned odds; h5fl_fac_test_op_code op_code; } h5fl_fac_test_op_odds; @@ -552,7 +558,8 @@ print_h5fl_fac_vector(h5fl_fac_test_vector *vector, h5fl_fac_test_token *tokens) #endif static void -init_h5fl_reg_vector(unsigned vec_size, h5fl_reg_test_vector *vector, unsigned num_tokens, h5fl_reg_test_token *tokens) +init_h5fl_reg_vector(unsigned vec_size, h5fl_reg_test_vector *vector, unsigned num_tokens, + h5fl_reg_test_token *tokens) { unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ unsigned curr_alloc_token; /* Current position for allocating tokens */ @@ -599,9 +606,9 @@ init_h5fl_reg_vector(unsigned vec_size, h5fl_reg_test_vector *vector, unsigned n unsigned new_token; /* RNG type to allocate */ - type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_reg_test_types); - new_token = get_new_h5fl_reg_token(tokens, &curr_alloc_token); - vector->op_vector[pos].token = &tokens[new_token]; + type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_reg_test_types); + new_token = get_new_h5fl_reg_token(tokens, &curr_alloc_token); + vector->op_vector[pos].token = &tokens[new_token]; vector->op_vector[pos].param.type_idx = type_idx; /* Mark token as used */ @@ -674,28 +681,32 @@ validate_h5fl_reg_token(const h5fl_reg_test_token *token) break; case H5FL_REG_ST_ZERO: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].zero, h5fl_reg_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].zero, + h5fl_reg_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_REG_ST_ZERO"); if (0 != v) return (1); break; case H5FL_REG_ST_FILL1: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill1, h5fl_reg_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill1, + h5fl_reg_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_REG_ST_FILL1"); if (0 != v) return (1); break; case H5FL_REG_ST_FILL2: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill2, h5fl_reg_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill2, + h5fl_reg_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_REG_ST_FILL2"); if (0 != v) return (1); break; case H5FL_REG_ST_FILL3: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill3, h5fl_reg_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill3, + h5fl_reg_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_REG_ST_FILL3"); if (0 != v) return (1); @@ -719,28 +730,32 @@ validate_h5fl_fac_token(const h5fl_fac_test_token *token) break; case H5FL_FAC_ST_ZERO: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].zero, h5fl_fac_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].zero, + h5fl_fac_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_FAC_ST_ZERO"); if (0 != v) return (1); break; case H5FL_FAC_ST_FILL1: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill1, h5fl_fac_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill1, + h5fl_fac_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_FAC_ST_FILL1"); if (0 != v) return (1); break; case H5FL_FAC_ST_FILL2: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill2, h5fl_fac_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill2, + h5fl_fac_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_FAC_ST_FILL2"); if (0 != v) return (1); break; case H5FL_FAC_ST_FILL3: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill3, h5fl_fac_test_types[token->type_idx].elmt_size); + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill3, + h5fl_fac_test_types[token->type_idx].elmt_size); VERIFY(v, 0, "H5FL_FAC_ST_FILL3"); if (0 != v) return (1); @@ -755,7 +770,8 @@ validate_h5fl_fac_token(const h5fl_fac_test_token *token) } static void -init_h5fl_fac_vector(unsigned vec_size, h5fl_fac_test_vector *vector, unsigned num_tokens, h5fl_fac_test_token *tokens) +init_h5fl_fac_vector(unsigned vec_size, h5fl_fac_test_vector *vector, unsigned num_tokens, + h5fl_fac_test_token *tokens) { unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ unsigned curr_alloc_token; /* Current position for allocating tokens */ @@ -802,9 +818,9 @@ init_h5fl_fac_vector(unsigned vec_size, h5fl_fac_test_vector *vector, unsigned n unsigned new_token; /* RNG type to allocate */ - type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_fac_test_types); - new_token = get_new_h5fl_fac_token(tokens, &curr_alloc_token); - vector->op_vector[pos].token = &tokens[new_token]; + type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_fac_test_types); + new_token = get_new_h5fl_fac_token(tokens, &curr_alloc_token); + vector->op_vector[pos].token = &tokens[new_token]; vector->op_vector[pos].param.type_idx = type_idx; /* Mark token as used */ @@ -1036,7 +1052,7 @@ run_h5fl_fac_vector(h5fl_fac_test_vector *vector) static H5TS_THREAD_RETURN_TYPE thread_h5fl_reg(void *_vectors) { - h5fl_reg_test_vector *vectors = (h5fl_reg_test_vector *)_vectors; + h5fl_reg_test_vector *vectors = (h5fl_reg_test_vector *)_vectors; unsigned errors = 0; H5TS_THREAD_RETURN_TYPE ret_value = (H5TS_THREAD_RETURN_TYPE)0; @@ -1060,10 +1076,9 @@ static h5fl_reg_test_vector *h5fl_reg_vectors[NUM_THREADS]; static void test_h5fl_reg(void) { - h5fl_reg_test_token *tokens[NUM_THREADS]; /* Test tokens */ - H5TS_thread_t threads[NUM_THREADS]; - herr_t result; - + h5fl_reg_test_token *tokens[NUM_THREADS]; /* Test tokens */ + H5TS_thread_t threads[NUM_THREADS]; + herr_t result; /* Output message about test being performed */ MESSAGE(7, ("Testing 'regular' H5FL operations\n")); @@ -1144,7 +1159,7 @@ test_h5fl_reg(void) static H5TS_THREAD_RETURN_TYPE thread_h5fl_fac(void *_vectors) { - h5fl_fac_test_vector *vectors = (h5fl_fac_test_vector *)_vectors; + h5fl_fac_test_vector *vectors = (h5fl_fac_test_vector *)_vectors; unsigned errors = 0; H5TS_THREAD_RETURN_TYPE ret_value = (H5TS_THREAD_RETURN_TYPE)0; @@ -1169,9 +1184,8 @@ static void test_h5fl_fac(void) { h5fl_fac_test_token *tokens[NUM_THREADS]; /* Test tokens */ - H5TS_thread_t threads[NUM_THREADS]; - herr_t result; - + H5TS_thread_t threads[NUM_THREADS]; + herr_t result; /* Output message about test being performed */ MESSAGE(7, ("Testing 'factory' H5FL operations\n")); From 613af269f837efb71ce80f9be43eaf5002ac3326 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:54:37 -0600 Subject: [PATCH 3/8] Reissue of file format discussion html file to doxygen (#5179) --- doxygen/dox/FileFormatDisc.dox | 1114 ++++++++++++++++++++++++++ doxygen/dox/TechnicalNotes.dox | 6 - doxygen/examples/FileFormat.html | 1273 ------------------------------ 3 files changed, 1114 insertions(+), 1279 deletions(-) create mode 100644 doxygen/dox/FileFormatDisc.dox delete mode 100644 doxygen/examples/FileFormat.html diff --git a/doxygen/dox/FileFormatDisc.dox b/doxygen/dox/FileFormatDisc.dox new file mode 100644 index 00000000000..8075840b97e --- /dev/null +++ b/doxygen/dox/FileFormatDisc.dox @@ -0,0 +1,1114 @@ + +/** \page FMTDISC HDF5 File Format Discussion + + +
+
Document's Audience:
+
Current H5 library designers and knowledgeable external developers.
+ +
Background Reading:
+
\ref FMT3
This describes the current HDF5 file format.
+
+ +\section sec_fmtdisc_intro Introduction +What is this document about?
+This document attempts to explain the HDF5 file format specification with a +few examples and describes some potential improvements to the format specification. + +\section sec_fmtdisc_exam File Format Examples +This section has several small programs and describes the format of a file +created with each of them. + +Example program one - Create an empty file: +\code +#include "hdf5.h" +#include + +int main() +{ + hid_t fid; /* File ID */ + herr_t ret; /* Generic return value */ + + /* Create the file */ + fid=H5Fcreate("example1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + assert(fid>=0); + + /* Close the file */ + ret=H5Fclose(fid); + assert(ret>=0); + + return(0); +} +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Super Block
bytebytebytebyte
\211'H''D''F'
\\r\\n\032\\n
0000
0880
416
0x00000003
0

0xffffffffffffffff

?

0xffffffffffffffff

+ + + + + + + + + + + + + + + + +
0

928

H5G_CACHED_STAB (1)
0
+ + + + + + + +

384


96

+
+
+ +\code +%h5debug example1.h5 + +Reading signature at address 0 (rel) +File Super Block... +File name: example1.h5 +File access flags 0x00000000 +File open reference count: 1 +Address of super block: 0 (abs) +Size of user block: 0 bytes +Super block version number: 0 +Free list version number: 0 +Root group symbol table entry version number: 0 +Shared header version number: 0 +Size of file offsets (haddr_t type): 8 bytes +Size of file lengths (hsize_t type): 8 bytes +Symbol table leaf node 1/2 rank: 4 +Symbol table internal node 1/2 rank: 16 +File consistency flags: 0x00000003 +Base address: 0 (abs) +Free list address: UNDEF (rel) +Address of driver information block: UNDEF (rel) +Root group symbol table entry: + Name offset into private heap: 0 + Object header address: 928 + Dirty: Yes + Cache info type: Symbol Table + Cached information: + B-tree address: 384 + Heap address: 96 +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Root Group Object Header
bytebytebytebyte
102
1
32
0x001116
0x010
+ + + + + + + +

384


96

+
00
0x000
+ +\code +%h5debug example1.h5 928 + +New address: 928 +Reading signature at address 928 (rel) +Object Header... +Dirty: 0 +Version: 1 +Header size (in bytes): 16 +Number of links: 1 +Number of messages (allocated): 2 (32) +Number of chunks (allocated): 1 (8) +Chunk 0... + Dirty: 0 + Address: 944 + Size in bytes: 32 +Message 0... + Message ID (sequence number): 0x0011 stab(0) + Shared message: No + Constant: Yes + Raw size in obj header: 16 bytes + Chunk number: 0 + Message Information: + B-tree address: 384 + Name heap address: 96 +Message 1... + Message ID (sequence number): 0x0000 null(0) + Shared message: No + Constant: No + Raw size in obj header: 0 bytes + Chunk number: 0 + Message Information: + +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Root Group Local Heap
bytebytebytebyte
'H''E''A''P'
0
256
8
128
+ +\code +%h5debug example1.h5 96 + +New address: 96 +Reading signature at address 96 (rel) +Local Heap... +Dirty: 0 +Header size (in bytes): 32 +Address of heap data: 128 +Data bytes allocated on disk: 256 +Data bytes allocated in core: 256 +Free Blocks (offset, size): + Block #0: 8, 248 +Percent of heap used: 3.12% +Data follows (`__' indicates free region)... + 0: 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ ........ + 16: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 32: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 48: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 64: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 80: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 96: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 112: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 128: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 144: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 160: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 176: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 192: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 208: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 224: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 240: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Root Group B-tree
bytebytebytebyte
'T''R''E''E'
000

0xffffffffffffffff


0xffffffffffffffff

+ +\code +%h5debug example1.h5 384 96 + +New address: 384 +Reading signature at address 384 (rel) +Tree type ID: H5B_SNODE_ID +Size of node: 544 +Size of raw (disk) key: 8 +Dirty flag: False +Number of initial dirty children: 0 +Level: 0 +Address of left sibling: UNDEF +Address of right sibling: UNDEF +Number of children (max): 0 (32) + +\endcode + +Example program two - Create a file with a single dataset in it: +\code +#include "hdf5.h" +#include + +int main() +{ + hid_t fid; /* File ID */ + hid_t sid; /* Dataspace ID */ + hid_t did; /* Dataset ID */ + herr_t ret; /* Generic return value */ + + /* Create the file */ + fid=H5Fcreate("example2.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + assert(fid>=0); + + /* Create a scalar dataspace for the dataset */ + sid=H5Screate(H5S_SCALAR); + assert(sid>=0); + + /* Create a trivial dataset */ + did=H5Dcreate(fid, "Dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT); + assert(did>=0); + + /* Close the dataset */ + ret=H5Dclose(did); + assert(ret>=0); + + /* Close the dataspace */ + ret=H5Sclose(sid); + assert(ret>=0); + + /* Close the file */ + ret=H5Fclose(fid); + assert(ret>=0); + + return(0); +} +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Super Block
bytebytebytebyte
\211'H''D''F'
\\r\\n\032\\n
0000
0880
416
0x00000003
0

0xffffffffffffffff

?

0xffffffffffffffff

+ + + + + + + + + + + + + + + + +
0

928

H5G_CACHED_STAB (1)
0
+ + + + + + + +

384


96

+
+
+ +\code +%h5debug example2.h5 + +Reading signature at address 0 (rel) +File Super Block... +File name: example2.h5 +File access flags 0x00000000 +File open reference count: 1 +Address of super block: 0 (abs) +Size of user block: 0 bytes +Super block version number: 0 +Free list version number: 0 +Root group symbol table entry version number: 0 +Shared header version number: 0 +Size of file offsets (haddr_t type): 8 bytes +Size of file lengths (hsize_t type): 8 bytes +Symbol table leaf node 1/2 rank: 4 +Symbol table internal node 1/2 rank: 16 +File consistency flags: 0x00000003 +Base address: 0 (abs) +Free list address: UNDEF (rel) +Address of driver information block: UNDEF (rel) +Root group symbol table entry: + Name offset into private heap: 0 + Object header address: 928 + Dirty: Yes + Cache info type: Symbol Table + Cached entry information: + B-tree address: 384 + Heap address: 96 +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Root Group Object Header
bytebytebytebyte
102
1
32
0x001116
0x010
+ + + + + + + +

384


96

+
00
0x000
+ +\code +%h5debug example2.h5 928 + +New address: 928 +Reading signature at address 928 (rel) +Object Header... +Dirty: 0 +Version: 1 +Header size (in bytes): 16 +Number of links: 1 +Number of messages (allocated): 2 (32) +Number of chunks (allocated): 1 (8) +Chunk 0... + Dirty: 0 + Address: 944 + Size in bytes: 32 +Message 0... + Message ID: 0x0011 stab(0) + Shared message: No + Constant: Yes + Raw size in obj header: 16 bytes + Chunk number: 0 + Message Information: + B-tree address: 384 + Name heap address: 96 +Message 1... + Message ID: 0x0000 null(0) + Shared message: No + Constant: No + Raw size in obj header: 0 bytes + Chunk number: 0 + Message Information: + +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Root Group Local Heap
bytebytebytebyte
'H''E''A''P'
0
256
16
128
+ +\code +%h5debug example2.h5 96 + +New address: 96 +Reading signature at address 96 (rel) +Local Heap... +Dirty: 0 +Header size (in bytes): 32 +Address of heap data: 128 +Data bytes allocated on disk: 256 +Data bytes allocated in core: 256 +Free Blocks (offset, size): + Block #0: 16, 240 +Percent of heap used: 6.25% +Data follows (`__' indicates free region)... + 0: 00 00 00 00 00 00 00 00 44 61 74 61 73 65 74 00 ........Dataset. + 16: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 32: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 48: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 64: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 80: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 96: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 112: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 128: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 144: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 160: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 176: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 192: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 208: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 224: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ + 240: __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Root Group B-tree
bytebytebytebyte
'T''R''E''E'
001

0xffffffffffffffff


0xffffffffffffffff


0


1248


8

+ +\code +%h5debug example2.h5 384 96 + +New address: 384 +Reading signature at address 384 (rel) +Tree type ID: H5B_SNODE_ID +Size of node: 544 +Size of raw (disk) key: 8 +Dirty flag: False +Number of initial dirty children: 0 +Level: 0 +Address of left sibling: UNDEF +Address of right sibling: UNDEF +Number of children (max): 1 (32) +Child 0... + Address: 1248 + Left Key: + Heap offset: 0 + Name : + Right Key: + Heap offset: 8 + Name : Dataset +\endcode + + + + + + + + + + + + + + + + + + + + + + + +
Root Group B-tree Symbol Table Node
bytebytebytebyte
'S''N''O''D'
101
+ + + + + + + + + + + + + + + + +
8

976

0
0


0


+
+ +\code +%h5debug example2.h5 1248 96 + +New address: 1248 +Reading signature at address 1248 (rel) +Symbol Table Node... +Dirty: No +Size of Node (in bytes): 328 +Number of Symbols: 1 of 8 +Symbol 0: + Name: `Dataset' + Name offset into private heap: 8 + Object header address: 976 + Dirty: No + Cache info type: Nothing Cached +\endcode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
'/Dataset' Object Header
bytebytebytebyte
Version: 1Reserved: 0Number of Header Messages: 6
Object Reference Count: 1
Total Object Header Size: 256
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fill Value Header Message
Message Type: 0x0005Message Data Size: 8
Flags: 0x01Reserved: 0
Version: 1Space Allocation Time: 2 (Late)Fill Value Writing Time: 0 (At allocation)Fill Value Defined: 0 (Undefined)
Fill Value Datatype Size: 0 (Use dataset's datatype for fill-value datatype)
+
+ + + + + + + + + + + + + + + + + + + Reserved: 0 + + + + + + + + + + + + + + + + + + + + + +
Datatype Header Message
Message Type: 0x0003Message Data Size: 16
Flags: 0x01
+ + + + + +
Version: 0x1Class: 0x0 (Fixed-Point)
+
Fixed-Point Bit-Field: 0x08 (Little-endian, No padding, Signed)
Size: 4
Bit Offset: 0Bit Precision: 32
Message Alignment Filler: -
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Dataspace Header Message
Message Type: 0x0001Message Data Size: 8
Flags: 0x00Reserved: 0
Version: 1Rank: 0 (Scalar)Flags: 0x00 (No maximum dimensions, no permutation information)Reserved: 0
Reserved: 0
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Layout Header Message
Message Type: 0x0008Message Data Size: 24
Flags: 0x00Reserved: 0
Version: 1Rank: 1 (Dataspace rank+1)Class: 1 (Contiguous)Reserved: 0
Reserved: 0

Address: 0xffffffffffffffff (Undefined)

Dimension 0 Size: 4 (Datatype size)
Message Alignment Filler: -
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Modification Date & Time Header Message
Message Type: 0x0012Message Data Size: 8
Flags: 0x00Reserved: 0
Version: 1Reserved: 0
Seconds Since Epoch: 1052401700 (2003-05-08 08:48:20 CDT)
+
+ + + + + + + + + + + + + + + + +
Null Header Message
Message Type: 0x0000Message Data Size: 144
Flags: 0x00Reserved: 0
+
+ +\code +%h5debug example2.h5 976 + +New address: 976 +Reading signature at address 976 (rel) +Object Header... +Dirty: 0 +Version: 1 +Header size (in bytes): 16 +Number of links: 1 +Number of messages (allocated): 6 (32) +Number of chunks (allocated): 1 (8) +Chunk 0... + Dirty: 0 + Address: 992 + Size in bytes: 256 +Message 0... + Message ID (sequence number): 0x0005 `fill_new' (0) + Shared: No + Constant: Yes + Raw size in obj header: 8 bytes + Chunk number: 0 + Message Information: + Version: 1 + Space Allocation Time: Late + Fill Time: On Allocation + Fill Value Defined: Undefined + Size: 0 + Data type: +Message 1... + Message ID (sequence number): 0x0003 data_type(0) + Shared message: No + Constant: Yes + Raw size in obj header: 16 bytes + Chunk number: 0 + Message Information: + Type class: integer + Size: 4 bytes + Byte order: little endian + Precision: 32 bits + Offset: 0 bits + Low pad type: zero + High pad type: zero + Sign scheme: 2's comp +Message 2... + Message ID (sequence number): 0x0001 simple_dspace(0) + Shared message: No + Constant: No + Raw size in obj header: 8 bytes + Chunk number: 0 + Message Information: + Rank: 0 +Message 3... + Message ID (sequence number): 0x0008 layout(0) + Shared message: No + Constant: No + Raw size in obj header: 24 bytes + Chunk number: 0 + Message Information: + Data address: UNDEF + Number of dimensions: 1 + Size: {4} +Message 4... + Message ID (sequence number): 0x0012 mtime_new(0) + Shared message: No + Constant: No + Raw size in obj header: 8 bytes + Chunk number: 0 + Message Information: + Time: 2003-03-05 14:52:00 CST +Message 5... + Message ID (sequence number): 0x0000 null(0) + Shared message: No + Constant: No + Raw size in obj header: 144 bytes + Chunk number: 0 + Message Information: + +\endcode + +*/ + diff --git a/doxygen/dox/TechnicalNotes.dox b/doxygen/dox/TechnicalNotes.dox index 47ba029cc92..05961f54162 100644 --- a/doxygen/dox/TechnicalNotes.dox +++ b/doxygen/dox/TechnicalNotes.dox @@ -24,9 +24,3 @@ */ -/** \page FMTDISC HDF5 File Format Discussion - -\htmlinclude FileFormat.html - -*/ - diff --git a/doxygen/examples/FileFormat.html b/doxygen/examples/FileFormat.html deleted file mode 100644 index 40d21138eb2..00000000000 --- a/doxygen/examples/FileFormat.html +++ /dev/null @@ -1,1273 +0,0 @@ - - - HDF5 File Format Discussion - - - - - - - -
-

HDF5 File Format Discussion

-

Quincey Koziol
- koziol@ncsa.uiuc.edu
- May 15, 2003 -

- -
    - -
  1. Document's Audience:

    - -
      -
    • Current H5 library designers and knowledgeable external developers.
    • -
    - -
  2. Background Reading:

    - -
    -
    HDF5 File Format Specification -
    This describes the current HDF5 file format. -
    - -
  3. Introduction:

    - -
    -
    What is this document about?
    -
    This document attempts to explain the HDF5 file format - specification with a few examples and describes some potential - improvements to the format specification. -

    -
    - -
  4. File Format Examples:

    - -

    This section has several small programs and describes the format of a file -created with each of them. -

    - -

    Example program one - Create an empty file: -

     
    -#include "hdf5.h"
    -#include 
    -
    -int main()
    -{
    -    hid_t fid;      /* File ID */
    -    herr_t ret;     /* Generic return value */
    -
    -    /* Create the file */
    -    fid=H5Fcreate("example1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    -    assert(fid>=0);
    -
    -    /* Close the file */
    -    ret=H5Fclose(fid);
    -    assert(ret>=0);
    -
    -    return(0);
    -}
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Super Block -
    bytebytebytebyte
    \211'H''D''F'
    \r\n\032\n
    0000
    0880
    416
    0x00000003
    0

    0xffffffffffffffff

    ?

    0xffffffffffffffff

    - - - - - - - - - - - - - - - - - - - - -
    0

    928

    H5G_CACHED_STAB (1)
    0
    - - - - - - - -

    384


    96

    -
    -
    -
    -
    -
     
    -%h5debug example1.h5
    -
    -Reading signature at address 0 (rel)
    -File Super Block...
    -File name:                                         example1.h5
    -File access flags                                  0x00000000
    -File open reference count:                         1
    -Address of super block:                            0 (abs)
    -Size of user block:                                0 bytes
    -Super block version number:                        0
    -Free list version number:                          0
    -Root group symbol table entry version number:      0
    -Shared header version number:                      0
    -Size of file offsets (haddr_t type):               8 bytes
    -Size of file lengths (hsize_t type):               8 bytes
    -Symbol table leaf node 1/2 rank:                   4
    -Symbol table internal node 1/2 rank:               16
    -File consistency flags:                            0x00000003
    -Base address:                                      0 (abs)
    -Free list address:                                 UNDEF (rel)
    -Address of driver information block:               UNDEF (rel)
    -Root group symbol table entry:
    -   Name offset into private heap:                  0
    -   Object header address:                          928
    -   Dirty:                                          Yes
    -   Cache info type:                                Symbol Table
    -   Cached information:
    -      B-tree address:                              384
    -      Heap address:                                96
    - 
    - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group Object Header -
    bytebytebytebyte
    102
    1
    32
    0x001116
    0x010
    - - - - - - - -

    384


    96

    -
    00
    0x000
    -
    -
    -
     
    -%h5debug example1.h5 928
    -
    -New address: 928
    -Reading signature at address 928 (rel)
    -Object Header...
    -Dirty:                                             0
    -Version:                                           1
    -Header size (in bytes):                            16
    -Number of links:                                   1
    -Number of messages (allocated):                    2 (32)
    -Number of chunks (allocated):                      1 (8)
    -Chunk 0...
    -   Dirty:                                          0
    -   Address:                                        944
    -   Size in bytes:                                  32
    -Message 0...
    -   Message ID (sequence number):                   0x0011 stab(0)
    -   Shared message:                                 No
    -   Constant:                                       Yes
    -   Raw size in obj header:                         16 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      B-tree address:                              384
    -      Name heap address:                           96
    -Message 1...
    -   Message ID (sequence number):                   0x0000 null(0)
    -   Shared message:                                 No
    -   Constant:                                       No
    -   Raw size in obj header:                         0 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group Local Heap -
    bytebytebytebyte
    'H''E''A''P'
    0
    256
    8
    128
    -
    -
    - -
     
    -%h5debug example1.h5 96
    -
    -New address: 96
    -Reading signature at address 96 (rel)
    -Local Heap...
    -Dirty:                                             0
    -Header size (in bytes):                            32
    -Address of heap data:                              128
    -Data bytes allocated on disk:                      256
    -Data bytes allocated in core:                      256
    -Free Blocks (offset, size):
    -   Block #0:                                        8,      248
    -Percent of heap used:                              3.12%
    -Data follows (`__' indicates free region)...
    -     0: 00 00 00 00 00 00 00 00  __ __ __ __ __ __ __ __ ........
    -    16: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    32: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    48: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    64: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    80: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    96: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   112: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   128: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   144: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   160: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   176: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   192: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   208: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   224: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -   240: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group B-tree -
    bytebytebytebyte
    'T''R''E''E'
    000

    0xffffffffffffffff


    0xffffffffffffffff

    -
    -
    -
     
    -%h5debug example1.h5 384 96
    -
    -New address: 384
    -Reading signature at address 384 (rel)
    -Tree type ID:                                      H5B_SNODE_ID
    -Size of node:                                      544
    -Size of raw (disk) key:                            8
    -Dirty flag:                                        False
    -Number of initial dirty children:                  0
    -Level:                                             0
    -Address of left sibling:                           UNDEF
    -Address of right sibling:                          UNDEF
    -Number of children (max):                          0 (32)
    -
    - 
    - -

    - -

    Example program two - Create a file with a single dataset in it: -

     
    -#include "hdf5.h"
    -#include 
    -
    -int main()
    -{
    -    hid_t fid;      /* File ID */
    -    hid_t sid;      /* Dataspace ID */
    -    hid_t did;      /* Dataset ID */
    -    herr_t ret;     /* Generic return value */
    -
    -    /* Create the file */
    -    fid=H5Fcreate("example2.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    -    assert(fid>=0);
    -
    -    /* Create a scalar dataspace for the dataset */
    -    sid=H5Screate(H5S_SCALAR);
    -    assert(sid>=0);
    -
    -    /* Create a trivial dataset */
    -    did=H5Dcreate(fid, "Dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT);
    -    assert(did>=0);
    -
    -    /* Close the dataset */
    -    ret=H5Dclose(did);
    -    assert(ret>=0);
    -
    -    /* Close the dataspace */
    -    ret=H5Sclose(sid);
    -    assert(ret>=0);
    -
    -    /* Close the file */
    -    ret=H5Fclose(fid);
    -    assert(ret>=0);
    -
    -    return(0);
    -}
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Super Block -
    bytebytebytebyte
    \211'H''D''F'
    \r\n\032\n
    0000
    0880
    416
    0x00000003
    0

    0xffffffffffffffff

    ?

    0xffffffffffffffff

    - - - - - - - - - - - - - - - - - - - - -
    0

    928

    H5G_CACHED_STAB (1)
    0
    - - - - - - - -

    384


    96

    -
    -
    -
    -
    -
     
    -%h5debug example2.h5
    -
    -Reading signature at address 0 (rel)
    -File Super Block...
    -File name:                                         example2.h5
    -File access flags                                  0x00000000
    -File open reference count:                         1
    -Address of super block:                            0 (abs)
    -Size of user block:                                0 bytes
    -Super block version number:                        0
    -Free list version number:                          0
    -Root group symbol table entry version number:      0
    -Shared header version number:                      0
    -Size of file offsets (haddr_t type):               8 bytes
    -Size of file lengths (hsize_t type):               8 bytes
    -Symbol table leaf node 1/2 rank:                   4
    -Symbol table internal node 1/2 rank:               16
    -File consistency flags:                            0x00000003
    -Base address:                                      0 (abs)
    -Free list address:                                 UNDEF (rel)
    -Address of driver information block:               UNDEF (rel)
    -Root group symbol table entry:
    -   Name offset into private heap:                  0
    -   Object header address:                          928
    -   Dirty:                                          Yes
    -   Cache info type:                                Symbol Table
    -   Cached entry information:
    -      B-tree address:                              384
    -      Heap address:                                96
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group Object Header -
    bytebytebytebyte
    102
    1
    32
    0x001116
    0x010
    - - - - - - - -

    384


    96

    -
    00
    0x000
    -
    -
    -
     
    -%h5debug example2.h5 928
    -
    -New address: 928
    -Reading signature at address 928 (rel)
    -Object Header...
    -Dirty:                                             0
    -Version:                                           1
    -Header size (in bytes):                            16
    -Number of links:                                   1
    -Number of messages (allocated):                    2 (32)
    -Number of chunks (allocated):                      1 (8)
    -Chunk 0...
    -   Dirty:                                          0
    -   Address:                                        944
    -   Size in bytes:                                  32
    -Message 0...
    -   Message ID:                                     0x0011 stab(0)
    -   Shared message:                                 No
    -   Constant:                                       Yes
    -   Raw size in obj header:                         16 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      B-tree address:                              384
    -      Name heap address:                           96
    -Message 1...
    -   Message ID:                                     0x0000 null(0)
    -   Shared message:                                 No
    -   Constant:                                       No
    -   Raw size in obj header:                         0 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group Local Heap -
    bytebytebytebyte
    'H''E''A''P'
    0
    256
    16
    128
    -
    -
    - -
     
    -%h5debug example2.h5 96
    -
    -New address: 96
    -Reading signature at address 96 (rel)
    -Local Heap...
    -Dirty:                                             0
    -Header size (in bytes):                            32
    -Address of heap data:                              128
    -Data bytes allocated on disk:                      256
    -Data bytes allocated in core:                      256
    -Free Blocks (offset, size):
    -   Block #0:                                       16,      240
    -Percent of heap used:                              6.25%
    -Data follows (`__' indicates free region)...
    -      0: 00 00 00 00 00 00 00 00  44 61 74 61 73 65 74 00 ........Dataset.
    -     16: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -     32: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -     48: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -     64: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -     80: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -     96: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    112: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    128: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    144: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    160: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    176: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    192: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    208: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    224: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    -    240: __ __ __ __ __ __ __ __  __ __ __ __ __ __ __ __
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group B-tree -
    bytebytebytebyte
    'T''R''E''E'
    001

    0xffffffffffffffff


    0xffffffffffffffff


    0


    1248


    8

    -
    -
    -
     
    -%h5debug example2.h5 384 96
    -
    -New address: 384
    -Reading signature at address 384 (rel)
    -Tree type ID:                                      H5B_SNODE_ID
    -Size of node:                                      544
    -Size of raw (disk) key:                            8
    -Dirty flag:                                        False
    -Number of initial dirty children:                  0
    -Level:                                             0
    -Address of left sibling:                           UNDEF
    -Address of right sibling:                          UNDEF
    -Number of children (max):                          1 (32)
    -Child 0...
    -   Address:                                        1248
    -   Left Key:
    -      Heap offset:                                 0
    -      Name :
    -   Right Key:
    -      Heap offset:                                 8
    -      Name :                                       Dataset
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    - Root Group B-tree Symbol Table Node -
    bytebytebytebyte
    'S''N''O''D'
    101
    - - - - - - - - - - - - - - - - - - - - -
    8

    976

    0
    0


    0


    -
    -
    -
    -
     
    -%h5debug example2.h5 1248 96
    -
    -New address: 1248
    -Reading signature at address 1248 (rel)
    -Symbol Table Node...
    -Dirty:                                             No
    -Size of Node (in bytes):                           328
    -Number of Symbols:                                 1 of 8
    -Symbol 0:
    -   Name:                                           `Dataset'
    -   Name offset into private heap:                  8
    -   Object header address:                          976
    -   Dirty:                                          No
    -   Cache info type:                                Nothing Cached
    - 
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - '/Dataset' Object Header -
    bytebytebytebyte
    Version: 1Reserved: 0Number of Header Messages: 6
    Object Reference Count: 1
    Total Object Header Size: 256
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Fill Value Header Message -
    Message Type: 0x0005Message Data Size: 8
    Flags: 0x01Reserved: 0
    Version: 1Space Allocation Time: 2 (Late)Fill Value Writing Time: 0 (At allocation)Fill Value Defined: 0 (Undefined)
    Fill Value Datatype Size: 0 (Use dataset's datatype for fill-value datatype)
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Datatype Header Message -
    Message Type: 0x0003Message Data Size: 16
    Flags: 0x01Reserved: 0
    - - - - - -
    Version: 0x1Class: 0x0 (Fixed-Point)
    -
    Fixed-Point Bit-Field: 0x08 (Little-endian, No padding, Signed)
    Size: 4
    Bit Offset: 0Bit Precision: 32
    Message Alignment Filler: -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Dataspace Header Message -
    Message Type: 0x0001Message Data Size: 8
    Flags: 0x00Reserved: 0
    Version: 1Rank: 0 (Scalar)Flags: 0x00 (No maximum dimensions, no permutation information)Reserved: 0
    Reserved: 0
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Layout Header Message -
    Message Type: 0x0008Message Data Size: 24
    Flags: 0x00Reserved: 0
    Version: 1Rank: 1 (Dataspace rank+1)Class: 1 (Contiguous)Reserved: 0
    Reserved: 0

    Address: 0xffffffffffffffff (Undefined)

    Dimension 0 Size: 4 (Datatype size)
    Message Alignment Filler: -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Modification Date & Time Header Message -
    Message Type: 0x0012Message Data Size: 8
    Flags: 0x00Reserved: 0
    Version: 1Reserved: 0
    Seconds Since Epoch: 1052401700 (2003-05-08 08:48:20 CDT)
    -
    - - - - - - - - - - - - - - - - - -
    - Null Header Message -
    Message Type: 0x0000Message Data Size: 144
    Flags: 0x00Reserved: 0
    -
    -
    -
    -
     
    -%h5debug example2.h5 976
    -
    -New address: 976
    -Reading signature at address 976 (rel)
    -Object Header...
    -Dirty:                                             0
    -Version:                                           1
    -Header size (in bytes):                            16
    -Number of links:                                   1
    -Number of messages (allocated):                    6 (32)
    -Number of chunks (allocated):                      1 (8)
    -Chunk 0...
    -   Dirty:                                          0
    -   Address:                                        992
    -   Size in bytes:                                  256
    -Message 0...
    -   Message ID (sequence number):                   0x0005 `fill_new' (0)
    -   Shared:                                         No
    -   Constant:                                       Yes
    -   Raw size in obj header:                         8 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      Version:                                     1
    -      Space Allocation Time:                       Late
    -      Fill Time:                                   On Allocation
    -      Fill Value Defined:                          Undefined
    -      Size:                                        0
    -      Data type:                                   
    -Message 1...
    -   Message ID (sequence number):                   0x0003 data_type(0)
    -   Shared message:                                 No
    -   Constant:                                       Yes
    -   Raw size in obj header:                         16 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      Type class:                                  integer
    -      Size:                                        4 bytes
    -      Byte order:                                  little endian
    -      Precision:                                   32 bits
    -      Offset:                                      0 bits
    -      Low pad type:                                zero
    -      High pad type:                               zero
    -      Sign scheme:                                 2's comp
    -Message 2...
    -   Message ID (sequence number):                   0x0001 simple_dspace(0)
    -   Shared message:                                 No
    -   Constant:                                       No
    -   Raw size in obj header:                         8 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      Rank:                                        0
    -Message 3...
    -   Message ID (sequence number):                   0x0008 layout(0)
    -   Shared message:                                 No
    -   Constant:                                       No
    -   Raw size in obj header:                         24 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      Data address:                                UNDEF
    -      Number of dimensions:                        1
    -      Size:                                        {4}
    -Message 4...
    -   Message ID (sequence number):                   0x0012 mtime_new(0)
    -   Shared message:                                 No
    -   Constant:                                       No
    -   Raw size in obj header:                         8 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      Time:                                        2003-03-05 14:52:00 CST
    -Message 5...
    -   Message ID (sequence number):                   0x0000 null(0)
    -   Shared message:                                 No
    -   Constant:                                       No
    -   Raw size in obj header:                         144 bytes
    -   Chunk number:                                   0
    -   Message Information:
    -      
    - 
    - -

    - -
- - -
- From 00270b7b391ab0d3a78dedf657a7dab390436966 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 28 Dec 2024 20:32:32 -0600 Subject: [PATCH 4/8] Add testing for 'block' operations Signed-off-by: Quincey Koziol --- test/ttsafe_h5fl.c | 944 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 776 insertions(+), 168 deletions(-) diff --git a/test/ttsafe_h5fl.c b/test/ttsafe_h5fl.c index a8abd1a52d2..e59387b38b8 100644 --- a/test/ttsafe_h5fl.c +++ b/test/ttsafe_h5fl.c @@ -81,7 +81,7 @@ typedef struct { unsigned char buf[55]; } h5fl_reg_test_type_12; -/* Free lists of the various types */ +/* 'regular' free lists of the various types */ H5FL_DEFINE_STATIC(h5fl_reg_test_type_1); H5FL_DEFINE_STATIC(h5fl_reg_test_type_2); H5FL_DEFINE_STATIC(h5fl_reg_test_type_3); @@ -95,6 +95,20 @@ H5FL_DEFINE_STATIC(h5fl_reg_test_type_10); H5FL_DEFINE_STATIC(h5fl_reg_test_type_11); H5FL_DEFINE_STATIC(h5fl_reg_test_type_12); +/* 'block' free lists of the various types */ +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_1); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_2); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_3); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_4); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_5); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_6); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_7); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_8); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_9); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_10); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_11); +H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_12); + typedef struct { H5FL_reg_head_t *free_list; size_t elmt_size; @@ -113,6 +127,11 @@ typedef struct { void *zero; } h5fl_fac_type_info; +typedef struct { + H5FL_blk_head_t *free_list; + size_t initial_size; +} h5fl_blk_type_info; + /* Array of all the 'regular' free lists & info */ static h5fl_reg_type_info h5fl_reg_test_types[] = { {&H5FL_REG_NAME(h5fl_reg_test_type_1), sizeof(h5fl_reg_test_type_1), NULL, NULL, NULL, NULL}, @@ -139,6 +158,22 @@ static h5fl_fac_type_info h5fl_fac_test_types[] = { {NULL, 34, NULL, NULL, NULL, NULL}, {NULL, 55, NULL, NULL, NULL, NULL}, }; +/* Array of all the 'block' free lists & info */ +static h5fl_blk_type_info h5fl_blk_test_types[] = { + {&H5FL_BLK_NAME(h5fl_blk_test_type_1), 16}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_2), 64}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_3), 256}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_4), 1}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_5), 2}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_6), 3}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_7), 5}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_8), 8}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_9), 13}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_10), 21}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_11), 34}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_12), 55}, +}; + typedef enum { H5FL_REG_OP_MALLOC, H5FL_REG_OP_CALLOC, @@ -159,6 +194,17 @@ typedef enum { H5FL_FAC_OP_FREE, } h5fl_fac_test_op_code; +typedef enum { + H5FL_BLK_OP_MALLOC, + H5FL_BLK_OP_CALLOC, + H5FL_BLK_OP_REALLOC, + H5FL_BLK_OP_ZERO, + H5FL_BLK_OP_FILL1, + H5FL_BLK_OP_FILL2, + H5FL_BLK_OP_FILL3, + H5FL_BLK_OP_FREE, +} h5fl_blk_test_op_code; + typedef enum { H5FL_REG_ST_UNINIT, H5FL_REG_ST_ZERO, @@ -175,6 +221,14 @@ typedef enum { H5FL_FAC_ST_FILL3 } h5fl_fac_token_state; +typedef enum { + H5FL_BLK_ST_UNINIT, + H5FL_BLK_ST_ZERO, + H5FL_BLK_ST_FILL1, + H5FL_BLK_ST_FILL2, + H5FL_BLK_ST_FILL3 +} h5fl_blk_token_state; + typedef struct { void *val; unsigned type_idx; @@ -187,6 +241,14 @@ typedef struct { h5fl_fac_token_state state; } h5fl_fac_test_token; +typedef struct { + unsigned char *val; + unsigned type_idx; + size_t curr_size; + int size_shift; + h5fl_blk_token_state state; +} h5fl_blk_test_token; + typedef union { unsigned type_idx; h5fl_reg_test_token *token; @@ -197,6 +259,12 @@ typedef union { h5fl_fac_test_token *token; } h5fl_fac_test_op_param; +typedef union { + unsigned type_idx; + h5fl_blk_test_token *token; + int size_shift; +} h5fl_blk_test_op_param; + typedef struct { h5fl_reg_test_op_code op_code; h5fl_reg_test_token *token; @@ -209,6 +277,12 @@ typedef struct { h5fl_fac_test_op_param param; } h5fl_fac_test_op; +typedef struct { + h5fl_blk_test_op_code op_code; + h5fl_blk_test_token *token; + h5fl_blk_test_op_param param; +} h5fl_blk_test_op; + typedef struct { unsigned vec_size; h5fl_reg_test_op *op_vector; @@ -219,6 +293,11 @@ typedef struct { h5fl_fac_test_op *op_vector; } h5fl_fac_test_vector; +typedef struct { + unsigned vec_size; + h5fl_blk_test_op *op_vector; +} h5fl_blk_test_vector; + typedef struct { unsigned odds; h5fl_reg_test_op_code op_code; @@ -229,6 +308,11 @@ typedef struct { h5fl_fac_test_op_code op_code; } h5fl_fac_test_op_odds; +typedef struct { + unsigned odds; + h5fl_blk_test_op_code op_code; +} h5fl_blk_test_op_odds; + /* Operation odds when token array is not full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_all_ops_odds[] = { @@ -253,6 +337,19 @@ static const h5fl_fac_test_op_odds h5fl_fac_all_ops_odds[] = { {302, H5FL_FAC_OP_FREE}, /* 30.2% = H5FL_FAC_OP_FREE */ }; +/* Operation odds when token array is not full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_blk_test_op_odds h5fl_blk_all_ops_odds[] = { + {171, H5FL_BLK_OP_MALLOC}, /* 17.1% = H5FL_BLK_OP_MALLOC */ + {171, H5FL_BLK_OP_CALLOC}, /* 17.1% = H5FL_BLK_OP_CALLOC */ + {200, H5FL_BLK_OP_REALLOC}, /* 20.0% = H5FL_BLK_OP_REALLOC */ + {64, H5FL_BLK_OP_ZERO}, /* 6.4% = H5FL_BLK_OP_ZERO */ + {64, H5FL_BLK_OP_FILL1}, /* 6.4% = H5FL_BLK_OP_FILL1 */ + {64, H5FL_BLK_OP_FILL2}, /* 6.4% = H5FL_BLK_OP_FILL2 */ + {64, H5FL_BLK_OP_FILL3}, /* 6.4% = H5FL_BLK_OP_FILL3 */ + {202, H5FL_BLK_OP_FREE}, /* 20.2% = H5FL_BLK_OP_FREE */ +}; + /* Operation odds when token array is full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_full_ops_odds[] = { @@ -277,6 +374,19 @@ static const h5fl_fac_test_op_odds h5fl_fac_full_ops_odds[] = { {584, H5FL_FAC_OP_FREE}, /* 58.4% = H5FL_FAC_OP_FREE */ }; +/* Operation odds when token array is full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_blk_test_op_odds h5fl_blk_full_ops_odds[] = { + {0, H5FL_BLK_OP_MALLOC}, /* 0% = H5FL_BLK_OP_MALLOC */ + {0, H5FL_BLK_OP_CALLOC}, /* 0% = H5FL_BLK_OP_CALLOC */ + {200, H5FL_BLK_OP_REALLOC}, /* 20.0% = H5FL_BLK_OP_REALLOC */ + {84, H5FL_BLK_OP_ZERO}, /* 8.4% = H5FL_BLK_OP_ZERO */ + {84, H5FL_BLK_OP_FILL1}, /* 8.4% = H5FL_BLK_OP_FILL1 */ + {84, H5FL_BLK_OP_FILL2}, /* 8.4% = H5FL_BLK_OP_FILL2 */ + {84, H5FL_BLK_OP_FILL3}, /* 8.4% = H5FL_BLK_OP_FILL3 */ + {464, H5FL_BLK_OP_FREE}, /* 46.4% = H5FL_BLK_OP_FREE */ +}; + /* Operation odds when vector is nearly full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_vec_almost_full_ops_odds[] = { @@ -301,6 +411,19 @@ static const h5fl_fac_test_op_odds h5fl_fac_vec_almost_full_ops_odds[] = { {0, H5FL_FAC_OP_FREE}, /* 0% = H5FL_FAC_OP_FREE */ }; +/* Operation odds when vector is nearly full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_blk_test_op_odds h5fl_blk_vec_almost_full_ops_odds[] = { + {0, H5FL_BLK_OP_MALLOC}, /* 0% = H5FL_BLK_OP_MALLOC */ + {0, H5FL_BLK_OP_CALLOC}, /* 0% = H5FL_BLK_OP_CALLOC */ + {400, H5FL_BLK_OP_REALLOC}, /* 40% = H5FL_BLK_OP_REALLOC */ + {150, H5FL_BLK_OP_ZERO}, /* 15% = H5FL_BLK_OP_ZERO */ + {150, H5FL_BLK_OP_FILL1}, /* 15% = H5FL_BLK_OP_FILL1 */ + {150, H5FL_BLK_OP_FILL2}, /* 15% = H5FL_BLK_OP_FILL2 */ + {150, H5FL_BLK_OP_FILL3}, /* 15% = H5FL_BLK_OP_FILL3 */ + {0, H5FL_BLK_OP_FREE}, /* 0% = H5FL_BLK_OP_FREE */ +}; + /* Operation odds when token array is empty */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_empty_ops_odds[] = { @@ -325,6 +448,19 @@ static const h5fl_fac_test_op_odds h5fl_fac_empty_ops_odds[] = { {0, H5FL_FAC_OP_FREE}, /* 0% = H5FL_FAC_OP_FREE */ }; +/* Operation odds when token array is empty */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_blk_test_op_odds h5fl_blk_empty_ops_odds[] = { + {500, H5FL_BLK_OP_MALLOC}, /* 50% = H5FL_BLK_OP_MALLOC */ + {500, H5FL_BLK_OP_CALLOC}, /* 50% = H5FL_BLK_OP_CALLOC */ + {0, H5FL_BLK_OP_REALLOC}, /* 0% = H5FL_BLK_OP_REALLOC */ + {0, H5FL_BLK_OP_ZERO}, /* 0% = H5FL_BLK_OP_ZERO */ + {0, H5FL_BLK_OP_FILL1}, /* 0% = H5FL_BLK_OP_FILL1 */ + {0, H5FL_BLK_OP_FILL2}, /* 0% = H5FL_BLK_OP_FILL2 */ + {0, H5FL_BLK_OP_FILL3}, /* 0% = H5FL_BLK_OP_FILL3 */ + {0, H5FL_BLK_OP_FREE}, /* 0% = H5FL_BLK_OP_FREE */ +}; + static unsigned get_new_h5fl_reg_token(h5fl_reg_test_token *tokens, unsigned *next_token) { @@ -365,6 +501,26 @@ get_new_h5fl_fac_token(h5fl_fac_test_token *tokens, unsigned *next_token) abort(); } +static unsigned +get_new_h5fl_blk_token(h5fl_blk_test_token *tokens, unsigned *next_token) +{ + unsigned curr_pos = *next_token; + unsigned start_pos = curr_pos; + + do { + /* Check for empty position */ + if (NULL == tokens[curr_pos].val) { + *next_token = (curr_pos + 1) % MAX_TOKENS; + return curr_pos; + } + + curr_pos = (curr_pos + 1) % MAX_TOKENS; + } while (curr_pos != start_pos); + + assert(curr_pos == start_pos && "Can't find empty position for new token"); + abort(); +} + static h5fl_reg_test_op_code get_new_h5fl_reg_op(const h5fl_reg_test_op_odds *op_odds) { @@ -397,6 +553,22 @@ get_new_h5fl_fac_op(const h5fl_fac_test_op_odds *op_odds) return op_odds[idx].op_code; } +static h5fl_blk_test_op_code +get_new_h5fl_blk_op(const h5fl_blk_test_op_odds *op_odds) +{ + unsigned idx; + unsigned rng; + + idx = 0; + rng = (unsigned)h5_local_rand() % 1000; + while (0 == op_odds[idx].odds || rng > op_odds[idx].odds) { + rng -= op_odds[idx].odds; + idx++; + } + + return op_odds[idx].op_code; +} + static unsigned get_active_h5fl_reg_token(h5fl_reg_test_token *tokens, unsigned num_possible_tokens) { @@ -435,6 +607,25 @@ get_active_h5fl_fac_token(h5fl_fac_test_token *tokens, unsigned num_possible_tok abort(); } +static unsigned +get_active_h5fl_blk_token(h5fl_blk_test_token *tokens, unsigned num_possible_tokens) +{ + unsigned curr_pos; + unsigned start_pos; + + start_pos = curr_pos = (unsigned)h5_local_rand() % num_possible_tokens; + do { + /* Check for active position */ + if (NULL != tokens[curr_pos].val) + return curr_pos; + + curr_pos = (curr_pos + 1) % num_possible_tokens; + } while (curr_pos != start_pos); + + assert(curr_pos == start_pos && "Can't find active token"); + abort(); +} + #if 0 static void print_h5fl_reg_vector(h5fl_reg_test_vector *vector, h5fl_reg_test_token *tokens) @@ -671,104 +862,6 @@ init_h5fl_reg_vector(unsigned vec_size, h5fl_reg_test_vector *vector, unsigned n assert(0 == num_active_tokens); } -static inline unsigned -validate_h5fl_reg_token(const h5fl_reg_test_token *token) -{ - int v; - - switch (token->state) { - case H5FL_REG_ST_UNINIT: - break; - - case H5FL_REG_ST_ZERO: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].zero, - h5fl_reg_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_REG_ST_ZERO"); - if (0 != v) - return (1); - break; - - case H5FL_REG_ST_FILL1: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill1, - h5fl_reg_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_REG_ST_FILL1"); - if (0 != v) - return (1); - break; - - case H5FL_REG_ST_FILL2: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill2, - h5fl_reg_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_REG_ST_FILL2"); - if (0 != v) - return (1); - break; - - case H5FL_REG_ST_FILL3: - v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill3, - h5fl_reg_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_REG_ST_FILL3"); - if (0 != v) - return (1); - break; - - default: - assert(0 && "Invalid state for token"); - abort(); - } - - return (0); -} - -static inline unsigned -validate_h5fl_fac_token(const h5fl_fac_test_token *token) -{ - int v; - - switch (token->state) { - case H5FL_FAC_ST_UNINIT: - break; - - case H5FL_FAC_ST_ZERO: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].zero, - h5fl_fac_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_FAC_ST_ZERO"); - if (0 != v) - return (1); - break; - - case H5FL_FAC_ST_FILL1: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill1, - h5fl_fac_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_FAC_ST_FILL1"); - if (0 != v) - return (1); - break; - - case H5FL_FAC_ST_FILL2: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill2, - h5fl_fac_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_FAC_ST_FILL2"); - if (0 != v) - return (1); - break; - - case H5FL_FAC_ST_FILL3: - v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill3, - h5fl_fac_test_types[token->type_idx].elmt_size); - VERIFY(v, 0, "H5FL_FAC_ST_FILL3"); - if (0 != v) - return (1); - break; - - default: - assert(0 && "Invalid state for token"); - abort(); - } - - return (0); -} - static void init_h5fl_fac_vector(unsigned vec_size, h5fl_fac_test_vector *vector, unsigned num_tokens, h5fl_fac_test_token *tokens) @@ -883,69 +976,347 @@ init_h5fl_fac_vector(unsigned vec_size, h5fl_fac_test_vector *vector, unsigned n assert(0 == num_active_tokens); } -static unsigned -run_h5fl_reg_vector(h5fl_reg_test_vector *vector) +static void +init_h5fl_blk_vector(unsigned vec_size, h5fl_blk_test_vector *vector, unsigned num_tokens, + h5fl_blk_test_token *tokens) { - /* Execute test vector */ - for (unsigned u = 0; u < vector->vec_size; u++) { - switch (vector->op_vector[u].op_code) { - case H5FL_REG_OP_MALLOC: - vector->op_vector[u].token->val = - H5FL_reg_malloc(h5fl_reg_test_types[vector->op_vector[u].param.type_idx].free_list); - CHECK_PTR(vector->op_vector[u].token->val, "H5FL_reg_malloc"); - if (NULL == vector->op_vector[u].token->val) - return (1); - vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->state = H5FL_REG_ST_UNINIT; - break; + unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ + unsigned curr_alloc_token; /* Current position for allocating tokens */ + unsigned pos; /* Current position in the test vector */ + bool tokens_wrapped = false; - case H5FL_REG_OP_CALLOC: - vector->op_vector[u].token->val = - H5FL_reg_calloc(h5fl_reg_test_types[vector->op_vector[u].param.type_idx].free_list); - CHECK_PTR(vector->op_vector[u].token->val, "H5FL_reg_calloc"); - if (NULL == vector->op_vector[u].token->val) - return (1); - vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; - break; + /* Allocate the test vector */ + vector->vec_size = vec_size; + vector->op_vector = calloc(vec_size, sizeof(h5fl_blk_test_op)); + CHECK_PTR(vector->op_vector, "calloc"); - case H5FL_REG_OP_ZERO: - if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) - return (1); - memset(vector->op_vector[u].token->val, 0, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; - break; + /* Fiil the test vector, leaving room to free active tokens */ + pos = 0; + curr_alloc_token = 0; + while (pos < (vec_size - num_active_tokens)) { + h5fl_blk_test_op_code op_code; - case H5FL_REG_OP_FILL1: - if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) - return (1); - memcpy(vector->op_vector[u].token->val, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill1, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_REG_ST_FILL1; - break; + /* Check for active tokens */ + /* (Also must have enough room for both alloc & free operations) */ + if (0 == num_active_tokens && pos < (vec_size - 2)) + op_code = get_new_h5fl_blk_op(h5fl_blk_empty_ops_odds); + else { + /* Don't create new tokens when there won't be enough room in the + * vector for both the alloc & free operations. + */ + if (pos > ((vec_size - num_active_tokens) - 2)) + op_code = get_new_h5fl_blk_op(h5fl_blk_vec_almost_full_ops_odds); + /* Don't create new tokens when the token array is full */ + else if (num_tokens == num_active_tokens) + op_code = get_new_h5fl_blk_op(h5fl_blk_full_ops_odds); + else + op_code = get_new_h5fl_blk_op(h5fl_blk_all_ops_odds); + } - case H5FL_REG_OP_FILL2: - if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) - if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) - return (1); - memcpy(vector->op_vector[u].token->val, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill2, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_REG_ST_FILL2; - break; + /* Set op code */ + vector->op_vector[pos].op_code = op_code; - case H5FL_REG_OP_FILL3: + /* Set up specific parameters for each op code */ + switch (op_code) { + case H5FL_BLK_OP_MALLOC: + case H5FL_BLK_OP_CALLOC: { + unsigned prev_alloc_token = curr_alloc_token; + unsigned type_idx; + unsigned new_token; + + /* RNG type to allocate */ + + type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_blk_test_types); + new_token = get_new_h5fl_blk_token(tokens, &curr_alloc_token); + vector->op_vector[pos].token = &tokens[new_token]; + vector->op_vector[pos].param.type_idx = type_idx; + + /* Mark token as used */ + tokens[new_token].val = (void *)(~(uintptr_t)NULL); + + /* Increment # of active tokens */ + num_active_tokens++; + + /* Check for tokens wrapping */ + if (curr_alloc_token < prev_alloc_token) + tokens_wrapped = true; + } break; + + case H5FL_BLK_OP_REALLOC: { + unsigned token_idx; + + token_idx = get_active_h5fl_blk_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + vector->op_vector[pos].param.size_shift = ((unsigned)h5_local_rand() & 0x10) ? 1 : -1; + } break; + + case H5FL_BLK_OP_ZERO: + case H5FL_BLK_OP_FILL1: + case H5FL_BLK_OP_FILL2: + case H5FL_BLK_OP_FILL3: + case H5FL_BLK_OP_FREE: { + unsigned token_idx; + + token_idx = get_active_h5fl_blk_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + + if (H5FL_BLK_OP_FREE == op_code) { + /* Mark token as free */ + tokens[token_idx].val = NULL; + + /* Decrement # of active tokens */ + num_active_tokens--; + } + } break; + + default: + assert(0 && "Invalid op code"); + abort(); + } + + pos++; + } + + /* Fill remainder of test vector with free operations */ + while (pos < vec_size) { + unsigned token_idx; + + /* Set op code */ + vector->op_vector[pos].op_code = H5FL_BLK_OP_FREE; + + token_idx = get_active_h5fl_blk_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + + /* Mark token as free */ + tokens[token_idx].val = NULL; + + /* Decrement # of active tokens */ + num_active_tokens--; + + pos++; + } + + assert(0 == num_active_tokens); +} + +static inline unsigned +validate_h5fl_reg_token(const h5fl_reg_test_token *token) +{ + int v; + + switch (token->state) { + case H5FL_REG_ST_UNINIT: + break; + + case H5FL_REG_ST_ZERO: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].zero, + h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_ZERO"); + if (0 != v) + return (1); + break; + + case H5FL_REG_ST_FILL1: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill1, + h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_FILL1"); + if (0 != v) + return (1); + break; + + case H5FL_REG_ST_FILL2: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill2, + h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_FILL2"); + if (0 != v) + return (1); + break; + + case H5FL_REG_ST_FILL3: + v = memcmp(token->val, h5fl_reg_test_types[token->type_idx].fill3, + h5fl_reg_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_REG_ST_FILL3"); + if (0 != v) + return (1); + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } + + return (0); +} + +static inline unsigned +validate_h5fl_fac_token(const h5fl_fac_test_token *token) +{ + int v; + + switch (token->state) { + case H5FL_FAC_ST_UNINIT: + break; + + case H5FL_FAC_ST_ZERO: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].zero, + h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_ZERO"); + if (0 != v) + return (1); + break; + + case H5FL_FAC_ST_FILL1: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill1, + h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_FILL1"); + if (0 != v) + return (1); + break; + + case H5FL_FAC_ST_FILL2: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill2, + h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_FILL2"); + if (0 != v) + return (1); + break; + + case H5FL_FAC_ST_FILL3: + v = memcmp(token->val, h5fl_fac_test_types[token->type_idx].fill3, + h5fl_fac_test_types[token->type_idx].elmt_size); + VERIFY(v, 0, "H5FL_FAC_ST_FILL3"); + if (0 != v) + return (1); + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } + + return (0); +} + +static inline unsigned +validate_h5fl_blk_token(const h5fl_blk_test_token *token) +{ + unsigned u; + + switch (token->state) { + case H5FL_BLK_ST_UNINIT: + break; + + case H5FL_BLK_ST_ZERO: + for (u = 0; u < token->curr_size; u++) { + VERIFY(token->val[u], 0, "H5FL_BLK_ST_ZERO"); + if (0 != token->val[u]) + return (1); + } + break; + + case H5FL_BLK_ST_FILL1: + for (u = 0; u < token->curr_size; u++) { + VERIFY(token->val[u], 1, "H5FL_BLK_ST_FILL1"); + if (1 != token->val[u]) + return (1); + } + break; + + case H5FL_BLK_ST_FILL2: + for (u = 0; u < token->curr_size; u++) { + VERIFY(token->val[u], 2, "H5FL_BLK_ST_FILL2"); + if (2 != token->val[u]) + return (1); + } + break; + + case H5FL_BLK_ST_FILL3: + for (u = 0; u < token->curr_size; u++) { + VERIFY(token->val[u], 3, "H5FL_BLK_ST_FILL3"); + if (3 != token->val[u]) + return (1); + } + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } + + return (0); +} + +static unsigned +run_h5fl_reg_vector(h5fl_reg_test_vector *vector) +{ + /* Execute test vector */ + for (unsigned u = 0; u < vector->vec_size; u++) { + switch (vector->op_vector[u].op_code) { + case H5FL_REG_OP_MALLOC: + vector->op_vector[u].token->val = + H5FL_reg_malloc(h5fl_reg_test_types[vector->op_vector[u].param.type_idx].free_list); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_reg_malloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->state = H5FL_REG_ST_UNINIT; + break; + + case H5FL_REG_OP_CALLOC: + vector->op_vector[u].token->val = + H5FL_reg_calloc(h5fl_reg_test_types[vector->op_vector[u].param.type_idx].free_list); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_reg_calloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; + break; + + case H5FL_REG_OP_ZERO: if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) return (1); - memcpy(vector->op_vector[u].token->val, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill3, - h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_REG_ST_FILL3; + if (H5FL_REG_ST_ZERO != vector->op_vector[u].token->state) { + memset(vector->op_vector[u].token->val, 0, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_ZERO; + } + break; + + case H5FL_REG_OP_FILL1: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) + return (1); + if (H5FL_REG_ST_FILL1 != vector->op_vector[u].token->state) { + memcpy(vector->op_vector[u].token->val, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill1, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL1; + } + break; + + case H5FL_REG_OP_FILL2: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) + return (1); + if (H5FL_REG_ST_FILL2 != vector->op_vector[u].token->state) { + memcpy(vector->op_vector[u].token->val, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill2, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL2; + } + break; + + case H5FL_REG_OP_FILL3: + if (H5FL_REG_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_reg_token(vector->op_vector[u].token)) + return (1); + if (H5FL_REG_ST_FILL3 != vector->op_vector[u].token->state) { + memcpy(vector->op_vector[u].token->val, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].fill3, + h5fl_reg_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_REG_ST_FILL3; + } break; case H5FL_REG_OP_FREE: @@ -996,39 +1367,47 @@ run_h5fl_fac_vector(h5fl_fac_test_vector *vector) if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) return (1); - memset(vector->op_vector[u].token->val, 0, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_FAC_ST_ZERO; + if (H5FL_FAC_ST_ZERO != vector->op_vector[u].token->state) { + memset(vector->op_vector[u].token->val, 0, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_ZERO; + } break; case H5FL_FAC_OP_FILL1: if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) return (1); - memcpy(vector->op_vector[u].token->val, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill1, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_FAC_ST_FILL1; + if (H5FL_FAC_ST_FILL1 != vector->op_vector[u].token->state) { + memcpy(vector->op_vector[u].token->val, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill1, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL1; + } break; case H5FL_FAC_OP_FILL2: if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) return (1); - memcpy(vector->op_vector[u].token->val, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill2, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_FAC_ST_FILL2; + if (H5FL_FAC_ST_FILL2 != vector->op_vector[u].token->state) { + memcpy(vector->op_vector[u].token->val, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill2, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL2; + } break; case H5FL_FAC_OP_FILL3: if (H5FL_FAC_ST_UNINIT != vector->op_vector[u].token->state) if (0 != validate_h5fl_fac_token(vector->op_vector[u].token)) return (1); - memcpy(vector->op_vector[u].token->val, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill3, - h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); - vector->op_vector[u].token->state = H5FL_FAC_ST_FILL3; + if (H5FL_FAC_ST_FILL3 != vector->op_vector[u].token->state) { + memcpy(vector->op_vector[u].token->val, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].fill3, + h5fl_fac_test_types[vector->op_vector[u].token->type_idx].elmt_size); + vector->op_vector[u].token->state = H5FL_FAC_ST_FILL3; + } break; case H5FL_FAC_OP_FREE: @@ -1049,6 +1428,159 @@ run_h5fl_fac_vector(h5fl_fac_test_vector *vector) return (0); } +static void +fill_h5fl_blk_vector(h5fl_blk_test_token *token) +{ + switch (token->state) { + case H5FL_BLK_ST_UNINIT: + break; + + case H5FL_BLK_ST_ZERO: + memset(token->val, 0, token->curr_size); + break; + + case H5FL_BLK_ST_FILL1: + memset(token->val, 1, token->curr_size); + break; + + case H5FL_BLK_ST_FILL2: + memset(token->val, 2, token->curr_size); + break; + + case H5FL_BLK_ST_FILL3: + memset(token->val, 3, token->curr_size); + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } +} + +static unsigned +run_h5fl_blk_vector(h5fl_blk_test_vector *vector) +{ + /* Execute test vector */ + for (unsigned u = 0; u < vector->vec_size; u++) { + switch (vector->op_vector[u].op_code) { + case H5FL_BLK_OP_MALLOC: + vector->op_vector[u].token->val = + H5FL_blk_malloc(h5fl_blk_test_types[vector->op_vector[u].param.type_idx].free_list, h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_blk_malloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->curr_size = h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size; + vector->op_vector[u].token->size_shift = 0; + vector->op_vector[u].token->state = H5FL_BLK_ST_UNINIT; + break; + + case H5FL_BLK_OP_CALLOC: + vector->op_vector[u].token->val = + H5FL_blk_calloc(h5fl_blk_test_types[vector->op_vector[u].param.type_idx].free_list, h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_blk_calloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->curr_size = h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size; + vector->op_vector[u].token->size_shift = 0; + vector->op_vector[u].token->state = H5FL_BLK_ST_ZERO; + break; + + case H5FL_BLK_OP_REALLOC: { + size_t new_size; + size_t prev_size; + + /* Choose new size for token's buffer */ + vector->op_vector[u].token->size_shift += vector->op_vector[u].param.size_shift; + if (vector->op_vector[u].token->size_shift > 0) + new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size << vector->op_vector[u].token->size_shift; + else if (vector->op_vector[u].token->size_shift < 0) { + new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size >> (-vector->op_vector[u].token->size_shift); + if (0 == new_size) + new_size = 1; + } + else + new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size; + + /* Validate current buffer */ + if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_blk_token(vector->op_vector[u].token)) + return (1); + + /* Reallocate buffer */ + vector->op_vector[u].token->val = + H5FL_blk_realloc(h5fl_blk_test_types[vector->op_vector[u].token->type_idx].free_list, vector->op_vector[u].token->val, new_size); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_blk_realloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + + /* Update size & value for buffer */ + prev_size = vector->op_vector[u].token->curr_size; + vector->op_vector[u].token->curr_size = new_size; + if (new_size > prev_size) + fill_h5fl_blk_vector(vector->op_vector[u].token); + } + break; + + case H5FL_BLK_OP_ZERO: + if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_blk_token(vector->op_vector[u].token)) + return (1); + if (H5FL_BLK_ST_ZERO != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_BLK_ST_ZERO; + memset(vector->op_vector[u].token->val, 0, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_BLK_OP_FILL1: + if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_blk_token(vector->op_vector[u].token)) + return (1); + if (H5FL_BLK_ST_FILL1 != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_BLK_ST_FILL1; + memset(vector->op_vector[u].token->val, 1, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_BLK_OP_FILL2: + if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_blk_token(vector->op_vector[u].token)) + return (1); + if (H5FL_BLK_ST_FILL2 != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_BLK_ST_FILL2; + memset(vector->op_vector[u].token->val, 2, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_BLK_OP_FILL3: + if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_blk_token(vector->op_vector[u].token)) + return (1); + if (H5FL_BLK_ST_FILL3 != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_BLK_ST_FILL3; + memset(vector->op_vector[u].token->val, 3, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_BLK_OP_FREE: + if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_blk_token(vector->op_vector[u].token)) + return (1); + H5FL_blk_free(h5fl_blk_test_types[vector->op_vector[u].token->type_idx].free_list, + vector->op_vector[u].token->val); + vector->op_vector[u].token->val = NULL; + break; + + default: + assert(0 && "Invalid op code"); + abort(); + } + } + + return (0); +} + static H5TS_THREAD_RETURN_TYPE thread_h5fl_reg(void *_vectors) { @@ -1275,6 +1807,81 @@ test_h5fl_fac(void) } } +static H5TS_THREAD_RETURN_TYPE +thread_h5fl_blk(void *_vectors) +{ + h5fl_blk_test_vector *vectors = (h5fl_blk_test_vector *)_vectors; + unsigned errors = 0; + H5TS_THREAD_RETURN_TYPE ret_value = (H5TS_THREAD_RETURN_TYPE)0; + + /* Randomly run a number of vectors */ + for (unsigned u = 0; u < NUM_ITERS_PER_THREAD; u++) { + unsigned rng = (unsigned)h5_local_rand() % NUM_VECTORS; + + /* Run the test vector */ + errors += run_h5fl_blk_vector(&vectors[rng]); + } + + if (errors > 0) + ret_value = (H5TS_THREAD_RETURN_TYPE)1; + + return ret_value; +} + +/* 'block' H5FL test vectors */ +static h5fl_blk_test_vector *h5fl_blk_vectors[NUM_THREADS]; + +static void +test_h5fl_blk(void) +{ + h5fl_blk_test_token *tokens[NUM_THREADS]; /* Test tokens */ + H5TS_thread_t threads[NUM_THREADS]; + herr_t result; + + /* Output message about test being performed */ + MESSAGE(7, ("Testing 'block' H5FL operations\n")); + + /* Initialize the test vectors */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + /* Allocate the test tokens */ + tokens[u] = calloc(MAX_TOKENS, sizeof(h5fl_blk_test_token)); + CHECK_PTR(tokens[u], "calloc"); + + /* Initialize the test vectors */ + h5fl_blk_vectors[u] = calloc(NUM_VECTORS, sizeof(h5fl_blk_test_vector)); + CHECK_PTR(h5fl_blk_vectors[u], "calloc"); + + for (unsigned v = 0; v < NUM_VECTORS; v++) + init_h5fl_blk_vector(NUM_TEST_OPS, &h5fl_blk_vectors[u][v], MAX_TOKENS, tokens[u]); + } + + /* Create threads and have them execute the vector */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + result = H5TS_thread_create(&threads[u], thread_h5fl_blk, h5fl_blk_vectors[u]); + CHECK_I(result, "H5TS_thread_create"); + } + + /* Wait for all threads */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + H5TS_THREAD_RETURN_TYPE thread_ret = (H5TS_THREAD_RETURN_TYPE)0; + + /* Join thread */ + result = H5TS_thread_join(threads[u], &thread_ret); + CHECK_I(result, "H5TS_thread_join"); + + /* Verify no errors from thread */ + VERIFY(thread_ret, (H5TS_THREAD_RETURN_TYPE)0, "error in thread"); + } + + /* Free test vectors & tokens */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + free(tokens[u]); + for (unsigned v = 0; v < NUM_VECTORS; v++) + free(h5fl_blk_vectors[u][v].op_vector); + free(h5fl_blk_vectors[u]); + } +} + /* ********************************************************************** * Test H5FL package @@ -1292,6 +1899,7 @@ tts_h5fl(const void H5_ATTR_UNUSED *params) /* Run tests */ test_h5fl_reg(); test_h5fl_fac(); + test_h5fl_blk(); } /* end tts_h5fl() */ #endif /*H5_HAVE_THREADS*/ From 2db28c576e6259308537337b9fea41d2254de8f3 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 02:34:26 +0000 Subject: [PATCH 5/8] Committing clang-format changes --- test/ttsafe_h5fl.c | 112 ++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/test/ttsafe_h5fl.c b/test/ttsafe_h5fl.c index e59387b38b8..e3e181df799 100644 --- a/test/ttsafe_h5fl.c +++ b/test/ttsafe_h5fl.c @@ -129,7 +129,7 @@ typedef struct { typedef struct { H5FL_blk_head_t *free_list; - size_t initial_size; + size_t initial_size; } h5fl_blk_type_info; /* Array of all the 'regular' free lists & info */ @@ -160,18 +160,12 @@ static h5fl_fac_type_info h5fl_fac_test_types[] = { /* Array of all the 'block' free lists & info */ static h5fl_blk_type_info h5fl_blk_test_types[] = { - {&H5FL_BLK_NAME(h5fl_blk_test_type_1), 16}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_2), 64}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_3), 256}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_4), 1}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_5), 2}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_6), 3}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_7), 5}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_8), 8}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_9), 13}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_10), 21}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_11), 34}, - {&H5FL_BLK_NAME(h5fl_blk_test_type_12), 55}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_1), 16}, {&H5FL_BLK_NAME(h5fl_blk_test_type_2), 64}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_3), 256}, {&H5FL_BLK_NAME(h5fl_blk_test_type_4), 1}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_5), 2}, {&H5FL_BLK_NAME(h5fl_blk_test_type_6), 3}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_7), 5}, {&H5FL_BLK_NAME(h5fl_blk_test_type_8), 8}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_9), 13}, {&H5FL_BLK_NAME(h5fl_blk_test_type_10), 21}, + {&H5FL_BLK_NAME(h5fl_blk_test_type_11), 34}, {&H5FL_BLK_NAME(h5fl_blk_test_type_12), 55}, }; typedef enum { @@ -242,10 +236,10 @@ typedef struct { } h5fl_fac_test_token; typedef struct { - unsigned char *val; + unsigned char *val; unsigned type_idx; - size_t curr_size; - int size_shift; + size_t curr_size; + int size_shift; h5fl_blk_token_state state; } h5fl_blk_test_token; @@ -262,7 +256,7 @@ typedef union { typedef union { unsigned type_idx; h5fl_blk_test_token *token; - int size_shift; + int size_shift; } h5fl_blk_test_op_param; typedef struct { @@ -340,14 +334,14 @@ static const h5fl_fac_test_op_odds h5fl_fac_all_ops_odds[] = { /* Operation odds when token array is not full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_blk_test_op_odds h5fl_blk_all_ops_odds[] = { - {171, H5FL_BLK_OP_MALLOC}, /* 17.1% = H5FL_BLK_OP_MALLOC */ - {171, H5FL_BLK_OP_CALLOC}, /* 17.1% = H5FL_BLK_OP_CALLOC */ + {171, H5FL_BLK_OP_MALLOC}, /* 17.1% = H5FL_BLK_OP_MALLOC */ + {171, H5FL_BLK_OP_CALLOC}, /* 17.1% = H5FL_BLK_OP_CALLOC */ {200, H5FL_BLK_OP_REALLOC}, /* 20.0% = H5FL_BLK_OP_REALLOC */ - {64, H5FL_BLK_OP_ZERO}, /* 6.4% = H5FL_BLK_OP_ZERO */ - {64, H5FL_BLK_OP_FILL1}, /* 6.4% = H5FL_BLK_OP_FILL1 */ - {64, H5FL_BLK_OP_FILL2}, /* 6.4% = H5FL_BLK_OP_FILL2 */ - {64, H5FL_BLK_OP_FILL3}, /* 6.4% = H5FL_BLK_OP_FILL3 */ - {202, H5FL_BLK_OP_FREE}, /* 20.2% = H5FL_BLK_OP_FREE */ + {64, H5FL_BLK_OP_ZERO}, /* 6.4% = H5FL_BLK_OP_ZERO */ + {64, H5FL_BLK_OP_FILL1}, /* 6.4% = H5FL_BLK_OP_FILL1 */ + {64, H5FL_BLK_OP_FILL2}, /* 6.4% = H5FL_BLK_OP_FILL2 */ + {64, H5FL_BLK_OP_FILL3}, /* 6.4% = H5FL_BLK_OP_FILL3 */ + {202, H5FL_BLK_OP_FREE}, /* 20.2% = H5FL_BLK_OP_FREE */ }; /* Operation odds when token array is full */ @@ -377,14 +371,14 @@ static const h5fl_fac_test_op_odds h5fl_fac_full_ops_odds[] = { /* Operation odds when token array is full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_blk_test_op_odds h5fl_blk_full_ops_odds[] = { - {0, H5FL_BLK_OP_MALLOC}, /* 0% = H5FL_BLK_OP_MALLOC */ - {0, H5FL_BLK_OP_CALLOC}, /* 0% = H5FL_BLK_OP_CALLOC */ - {200, H5FL_BLK_OP_REALLOC}, /* 20.0% = H5FL_BLK_OP_REALLOC */ - {84, H5FL_BLK_OP_ZERO}, /* 8.4% = H5FL_BLK_OP_ZERO */ - {84, H5FL_BLK_OP_FILL1}, /* 8.4% = H5FL_BLK_OP_FILL1 */ - {84, H5FL_BLK_OP_FILL2}, /* 8.4% = H5FL_BLK_OP_FILL2 */ - {84, H5FL_BLK_OP_FILL3}, /* 8.4% = H5FL_BLK_OP_FILL3 */ - {464, H5FL_BLK_OP_FREE}, /* 46.4% = H5FL_BLK_OP_FREE */ + {0, H5FL_BLK_OP_MALLOC}, /* 0% = H5FL_BLK_OP_MALLOC */ + {0, H5FL_BLK_OP_CALLOC}, /* 0% = H5FL_BLK_OP_CALLOC */ + {200, H5FL_BLK_OP_REALLOC}, /* 20.0% = H5FL_BLK_OP_REALLOC */ + {84, H5FL_BLK_OP_ZERO}, /* 8.4% = H5FL_BLK_OP_ZERO */ + {84, H5FL_BLK_OP_FILL1}, /* 8.4% = H5FL_BLK_OP_FILL1 */ + {84, H5FL_BLK_OP_FILL2}, /* 8.4% = H5FL_BLK_OP_FILL2 */ + {84, H5FL_BLK_OP_FILL3}, /* 8.4% = H5FL_BLK_OP_FILL3 */ + {464, H5FL_BLK_OP_FREE}, /* 46.4% = H5FL_BLK_OP_FREE */ }; /* Operation odds when vector is nearly full */ @@ -414,14 +408,14 @@ static const h5fl_fac_test_op_odds h5fl_fac_vec_almost_full_ops_odds[] = { /* Operation odds when vector is nearly full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_blk_test_op_odds h5fl_blk_vec_almost_full_ops_odds[] = { - {0, H5FL_BLK_OP_MALLOC}, /* 0% = H5FL_BLK_OP_MALLOC */ - {0, H5FL_BLK_OP_CALLOC}, /* 0% = H5FL_BLK_OP_CALLOC */ - {400, H5FL_BLK_OP_REALLOC}, /* 40% = H5FL_BLK_OP_REALLOC */ - {150, H5FL_BLK_OP_ZERO}, /* 15% = H5FL_BLK_OP_ZERO */ - {150, H5FL_BLK_OP_FILL1}, /* 15% = H5FL_BLK_OP_FILL1 */ - {150, H5FL_BLK_OP_FILL2}, /* 15% = H5FL_BLK_OP_FILL2 */ - {150, H5FL_BLK_OP_FILL3}, /* 15% = H5FL_BLK_OP_FILL3 */ - {0, H5FL_BLK_OP_FREE}, /* 0% = H5FL_BLK_OP_FREE */ + {0, H5FL_BLK_OP_MALLOC}, /* 0% = H5FL_BLK_OP_MALLOC */ + {0, H5FL_BLK_OP_CALLOC}, /* 0% = H5FL_BLK_OP_CALLOC */ + {400, H5FL_BLK_OP_REALLOC}, /* 40% = H5FL_BLK_OP_REALLOC */ + {150, H5FL_BLK_OP_ZERO}, /* 15% = H5FL_BLK_OP_ZERO */ + {150, H5FL_BLK_OP_FILL1}, /* 15% = H5FL_BLK_OP_FILL1 */ + {150, H5FL_BLK_OP_FILL2}, /* 15% = H5FL_BLK_OP_FILL2 */ + {150, H5FL_BLK_OP_FILL3}, /* 15% = H5FL_BLK_OP_FILL3 */ + {0, H5FL_BLK_OP_FREE}, /* 0% = H5FL_BLK_OP_FREE */ }; /* Operation odds when token array is empty */ @@ -453,7 +447,7 @@ static const h5fl_fac_test_op_odds h5fl_fac_empty_ops_odds[] = { static const h5fl_blk_test_op_odds h5fl_blk_empty_ops_odds[] = { {500, H5FL_BLK_OP_MALLOC}, /* 50% = H5FL_BLK_OP_MALLOC */ {500, H5FL_BLK_OP_CALLOC}, /* 50% = H5FL_BLK_OP_CALLOC */ - {0, H5FL_BLK_OP_REALLOC}, /* 0% = H5FL_BLK_OP_REALLOC */ + {0, H5FL_BLK_OP_REALLOC}, /* 0% = H5FL_BLK_OP_REALLOC */ {0, H5FL_BLK_OP_ZERO}, /* 0% = H5FL_BLK_OP_ZERO */ {0, H5FL_BLK_OP_FILL1}, /* 0% = H5FL_BLK_OP_FILL1 */ {0, H5FL_BLK_OP_FILL2}, /* 0% = H5FL_BLK_OP_FILL2 */ @@ -1046,7 +1040,7 @@ init_h5fl_blk_vector(unsigned vec_size, h5fl_blk_test_vector *vector, unsigned n unsigned token_idx; token_idx = get_active_h5fl_blk_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); - vector->op_vector[pos].token = &tokens[token_idx]; + vector->op_vector[pos].token = &tokens[token_idx]; vector->op_vector[pos].param.size_shift = ((unsigned)h5_local_rand() & 0x10) ? 1 : -1; } break; @@ -1465,26 +1459,30 @@ run_h5fl_blk_vector(h5fl_blk_test_vector *vector) switch (vector->op_vector[u].op_code) { case H5FL_BLK_OP_MALLOC: vector->op_vector[u].token->val = - H5FL_blk_malloc(h5fl_blk_test_types[vector->op_vector[u].param.type_idx].free_list, h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size); + H5FL_blk_malloc(h5fl_blk_test_types[vector->op_vector[u].param.type_idx].free_list, + h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size); CHECK_PTR(vector->op_vector[u].token->val, "H5FL_blk_malloc"); if (NULL == vector->op_vector[u].token->val) return (1); vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->curr_size = h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size; - vector->op_vector[u].token->size_shift = 0; - vector->op_vector[u].token->state = H5FL_BLK_ST_UNINIT; + vector->op_vector[u].token->curr_size = + h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size; + vector->op_vector[u].token->size_shift = 0; + vector->op_vector[u].token->state = H5FL_BLK_ST_UNINIT; break; case H5FL_BLK_OP_CALLOC: vector->op_vector[u].token->val = - H5FL_blk_calloc(h5fl_blk_test_types[vector->op_vector[u].param.type_idx].free_list, h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size); + H5FL_blk_calloc(h5fl_blk_test_types[vector->op_vector[u].param.type_idx].free_list, + h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size); CHECK_PTR(vector->op_vector[u].token->val, "H5FL_blk_calloc"); if (NULL == vector->op_vector[u].token->val) return (1); vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; - vector->op_vector[u].token->curr_size = h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size; - vector->op_vector[u].token->size_shift = 0; - vector->op_vector[u].token->state = H5FL_BLK_ST_ZERO; + vector->op_vector[u].token->curr_size = + h5fl_blk_test_types[vector->op_vector[u].param.type_idx].initial_size; + vector->op_vector[u].token->size_shift = 0; + vector->op_vector[u].token->state = H5FL_BLK_ST_ZERO; break; case H5FL_BLK_OP_REALLOC: { @@ -1494,9 +1492,11 @@ run_h5fl_blk_vector(h5fl_blk_test_vector *vector) /* Choose new size for token's buffer */ vector->op_vector[u].token->size_shift += vector->op_vector[u].param.size_shift; if (vector->op_vector[u].token->size_shift > 0) - new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size << vector->op_vector[u].token->size_shift; + new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size + << vector->op_vector[u].token->size_shift; else if (vector->op_vector[u].token->size_shift < 0) { - new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size >> (-vector->op_vector[u].token->size_shift); + new_size = h5fl_blk_test_types[vector->op_vector[u].token->type_idx].initial_size >> + (-vector->op_vector[u].token->size_shift); if (0 == new_size) new_size = 1; } @@ -1510,18 +1510,18 @@ run_h5fl_blk_vector(h5fl_blk_test_vector *vector) /* Reallocate buffer */ vector->op_vector[u].token->val = - H5FL_blk_realloc(h5fl_blk_test_types[vector->op_vector[u].token->type_idx].free_list, vector->op_vector[u].token->val, new_size); + H5FL_blk_realloc(h5fl_blk_test_types[vector->op_vector[u].token->type_idx].free_list, + vector->op_vector[u].token->val, new_size); CHECK_PTR(vector->op_vector[u].token->val, "H5FL_blk_realloc"); if (NULL == vector->op_vector[u].token->val) return (1); /* Update size & value for buffer */ - prev_size = vector->op_vector[u].token->curr_size; + prev_size = vector->op_vector[u].token->curr_size; vector->op_vector[u].token->curr_size = new_size; if (new_size > prev_size) fill_h5fl_blk_vector(vector->op_vector[u].token); - } - break; + } break; case H5FL_BLK_OP_ZERO: if (H5FL_BLK_ST_UNINIT != vector->op_vector[u].token->state) From d96adf88dffe679db18dc42a82c228f1185cd37c Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sun, 29 Dec 2024 18:18:45 -0600 Subject: [PATCH 6/8] Remove assert() that's incorrect in concurrent mode Signed-off-by: Quincey Koziol --- src/H5FL.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/H5FL.c b/src/H5FL.c index 9b33d40813a..575bab14053 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -1467,9 +1467,6 @@ H5FL__blk_gc(void) gc_node = gc_node->next; } /* end while */ - /* Double check that all the memory on the free lists are recycled */ - assert(H5TS_ATOMIC_LOAD_SIZE_T(&H5FL_blk_gc_head.mem_freed) == 0); - #ifdef H5_HAVE_CONCURRENCY /* Release the mutex protecting the list of lists */ if (H5TS_dlftt_mutex_release(&H5FL_blk_gc_head.mutex) < 0) @@ -2025,9 +2022,6 @@ H5FL__arr_gc(void) gc_arr_node = gc_arr_node->next; } /* end while */ - /* Double check that all the memory on the free lists are recycled */ - assert(H5TS_ATOMIC_LOAD_SIZE_T(&H5FL_arr_gc_head.mem_freed) == 0); - #ifdef H5_HAVE_CONCURRENCY /* Release the mutex protecting the list of lists */ if (H5TS_dlftt_mutex_release(&H5FL_arr_gc_head.mutex) < 0) @@ -2594,9 +2588,6 @@ H5FL__fac_gc(void) gc_node = gc_node->next; } /* end while */ - /* Double check that all the memory on the free lists is recycled */ - assert(H5TS_ATOMIC_LOAD_SIZE_T(&H5FL_fac_gc_head.mem_freed) == 0); - #ifdef H5_HAVE_CONCURRENCY /* Release the mutex protecting the list of lists */ if (H5TS_dlftt_mutex_release(&H5FL_fac_gc_head.mutex) < 0) From 99aafb5f4c4765bb25704110d1e47875d3342cb6 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sun, 29 Dec 2024 20:07:50 -0600 Subject: [PATCH 7/8] Add 'array' testing Signed-off-by: Quincey Koziol --- test/ttsafe_h5fl.c | 629 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) diff --git a/test/ttsafe_h5fl.c b/test/ttsafe_h5fl.c index e3e181df799..0963337cc8b 100644 --- a/test/ttsafe_h5fl.c +++ b/test/ttsafe_h5fl.c @@ -81,6 +81,55 @@ typedef struct { unsigned char buf[55]; } h5fl_reg_test_type_12; +/* Types of various sizes, for array free lists */ +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_1; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_2; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_3; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_4; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_5; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_6; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_7; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_8; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_9; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_10; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_11; + +typedef struct { + unsigned char buf[1]; +} h5fl_arr_test_type_12; + /* 'regular' free lists of the various types */ H5FL_DEFINE_STATIC(h5fl_reg_test_type_1); H5FL_DEFINE_STATIC(h5fl_reg_test_type_2); @@ -109,6 +158,20 @@ H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_10); H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_11); H5FL_BLK_DEFINE_STATIC(h5fl_blk_test_type_12); +/* 'array' free lists of the various types */ +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_1, 16); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_2, 64); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_3, 256); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_4, 2); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_5, 3); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_6, 5); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_7, 8); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_8, 13); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_9, 21); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_10, 34); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_11, 55); +H5FL_ARR_DEFINE_STATIC(h5fl_arr_test_type_12, 89); + typedef struct { H5FL_reg_head_t *free_list; size_t elmt_size; @@ -132,6 +195,11 @@ typedef struct { size_t initial_size; } h5fl_blk_type_info; +typedef struct { + H5FL_arr_head_t *free_list; + unsigned max_size; +} h5fl_arr_type_info; + /* Array of all the 'regular' free lists & info */ static h5fl_reg_type_info h5fl_reg_test_types[] = { {&H5FL_REG_NAME(h5fl_reg_test_type_1), sizeof(h5fl_reg_test_type_1), NULL, NULL, NULL, NULL}, @@ -168,6 +236,16 @@ static h5fl_blk_type_info h5fl_blk_test_types[] = { {&H5FL_BLK_NAME(h5fl_blk_test_type_11), 34}, {&H5FL_BLK_NAME(h5fl_blk_test_type_12), 55}, }; +/* Array of all the 'array' free lists & info */ +static h5fl_arr_type_info h5fl_arr_test_types[] = { + {&H5FL_ARR_NAME(h5fl_arr_test_type_1), 16}, {&H5FL_ARR_NAME(h5fl_arr_test_type_2), 64}, + {&H5FL_ARR_NAME(h5fl_arr_test_type_3), 256}, {&H5FL_ARR_NAME(h5fl_arr_test_type_4), 2}, + {&H5FL_ARR_NAME(h5fl_arr_test_type_5), 3}, {&H5FL_ARR_NAME(h5fl_arr_test_type_6), 5}, + {&H5FL_ARR_NAME(h5fl_arr_test_type_7), 8}, {&H5FL_ARR_NAME(h5fl_arr_test_type_8), 13}, + {&H5FL_ARR_NAME(h5fl_arr_test_type_9), 21}, {&H5FL_ARR_NAME(h5fl_arr_test_type_10), 34}, + {&H5FL_ARR_NAME(h5fl_arr_test_type_11), 55}, {&H5FL_ARR_NAME(h5fl_arr_test_type_12), 89}, +}; + typedef enum { H5FL_REG_OP_MALLOC, H5FL_REG_OP_CALLOC, @@ -199,6 +277,17 @@ typedef enum { H5FL_BLK_OP_FREE, } h5fl_blk_test_op_code; +typedef enum { + H5FL_ARR_OP_MALLOC, + H5FL_ARR_OP_CALLOC, + H5FL_ARR_OP_REALLOC, + H5FL_ARR_OP_ZERO, + H5FL_ARR_OP_FILL1, + H5FL_ARR_OP_FILL2, + H5FL_ARR_OP_FILL3, + H5FL_ARR_OP_FREE, +} h5fl_arr_test_op_code; + typedef enum { H5FL_REG_ST_UNINIT, H5FL_REG_ST_ZERO, @@ -223,6 +312,14 @@ typedef enum { H5FL_BLK_ST_FILL3 } h5fl_blk_token_state; +typedef enum { + H5FL_ARR_ST_UNINIT, + H5FL_ARR_ST_ZERO, + H5FL_ARR_ST_FILL1, + H5FL_ARR_ST_FILL2, + H5FL_ARR_ST_FILL3 +} h5fl_arr_token_state; + typedef struct { void *val; unsigned type_idx; @@ -243,6 +340,13 @@ typedef struct { h5fl_blk_token_state state; } h5fl_blk_test_token; +typedef struct { + unsigned char *val; + unsigned type_idx; + unsigned curr_size; + h5fl_arr_token_state state; +} h5fl_arr_test_token; + typedef union { unsigned type_idx; h5fl_reg_test_token *token; @@ -259,6 +363,12 @@ typedef union { int size_shift; } h5fl_blk_test_op_param; +typedef union { + unsigned type_idx; + h5fl_arr_test_token *token; + unsigned rng_size; +} h5fl_arr_test_op_param; + typedef struct { h5fl_reg_test_op_code op_code; h5fl_reg_test_token *token; @@ -277,6 +387,12 @@ typedef struct { h5fl_blk_test_op_param param; } h5fl_blk_test_op; +typedef struct { + h5fl_arr_test_op_code op_code; + h5fl_arr_test_token *token; + h5fl_arr_test_op_param param; +} h5fl_arr_test_op; + typedef struct { unsigned vec_size; h5fl_reg_test_op *op_vector; @@ -292,6 +408,11 @@ typedef struct { h5fl_blk_test_op *op_vector; } h5fl_blk_test_vector; +typedef struct { + unsigned vec_size; + h5fl_arr_test_op *op_vector; +} h5fl_arr_test_vector; + typedef struct { unsigned odds; h5fl_reg_test_op_code op_code; @@ -307,6 +428,11 @@ typedef struct { h5fl_blk_test_op_code op_code; } h5fl_blk_test_op_odds; +typedef struct { + unsigned odds; + h5fl_arr_test_op_code op_code; +} h5fl_arr_test_op_odds; + /* Operation odds when token array is not full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_all_ops_odds[] = { @@ -344,6 +470,19 @@ static const h5fl_blk_test_op_odds h5fl_blk_all_ops_odds[] = { {202, H5FL_BLK_OP_FREE}, /* 20.2% = H5FL_BLK_OP_FREE */ }; +/* Operation odds when token array is not full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_arr_test_op_odds h5fl_arr_all_ops_odds[] = { + {171, H5FL_ARR_OP_MALLOC}, /* 17.1% = H5FL_ARR_OP_MALLOC */ + {171, H5FL_ARR_OP_CALLOC}, /* 17.1% = H5FL_ARR_OP_CALLOC */ + {200, H5FL_ARR_OP_REALLOC}, /* 20.0% = H5FL_ARR_OP_REALLOC */ + {64, H5FL_ARR_OP_ZERO}, /* 6.4% = H5FL_ARR_OP_ZERO */ + {64, H5FL_ARR_OP_FILL1}, /* 6.4% = H5FL_ARR_OP_FILL1 */ + {64, H5FL_ARR_OP_FILL2}, /* 6.4% = H5FL_ARR_OP_FILL2 */ + {64, H5FL_ARR_OP_FILL3}, /* 6.4% = H5FL_ARR_OP_FILL3 */ + {202, H5FL_ARR_OP_FREE}, /* 20.2% = H5FL_ARR_OP_FREE */ +}; + /* Operation odds when token array is full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_full_ops_odds[] = { @@ -381,6 +520,19 @@ static const h5fl_blk_test_op_odds h5fl_blk_full_ops_odds[] = { {464, H5FL_BLK_OP_FREE}, /* 46.4% = H5FL_BLK_OP_FREE */ }; +/* Operation odds when token array is full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_arr_test_op_odds h5fl_arr_full_ops_odds[] = { + {0, H5FL_ARR_OP_MALLOC}, /* 0% = H5FL_ARR_OP_MALLOC */ + {0, H5FL_ARR_OP_CALLOC}, /* 0% = H5FL_ARR_OP_CALLOC */ + {200, H5FL_ARR_OP_REALLOC}, /* 20.0% = H5FL_ARR_OP_REALLOC */ + {84, H5FL_ARR_OP_ZERO}, /* 8.4% = H5FL_ARR_OP_ZERO */ + {84, H5FL_ARR_OP_FILL1}, /* 8.4% = H5FL_ARR_OP_FILL1 */ + {84, H5FL_ARR_OP_FILL2}, /* 8.4% = H5FL_ARR_OP_FILL2 */ + {84, H5FL_ARR_OP_FILL3}, /* 8.4% = H5FL_ARR_OP_FILL3 */ + {464, H5FL_ARR_OP_FREE}, /* 46.4% = H5FL_ARR_OP_FREE */ +}; + /* Operation odds when vector is nearly full */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_vec_almost_full_ops_odds[] = { @@ -418,6 +570,19 @@ static const h5fl_blk_test_op_odds h5fl_blk_vec_almost_full_ops_odds[] = { {0, H5FL_BLK_OP_FREE}, /* 0% = H5FL_BLK_OP_FREE */ }; +/* Operation odds when vector is nearly full */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_arr_test_op_odds h5fl_arr_vec_almost_full_ops_odds[] = { + {0, H5FL_ARR_OP_MALLOC}, /* 0% = H5FL_ARR_OP_MALLOC */ + {0, H5FL_ARR_OP_CALLOC}, /* 0% = H5FL_ARR_OP_CALLOC */ + {400, H5FL_ARR_OP_REALLOC}, /* 40% = H5FL_ARR_OP_REALLOC */ + {150, H5FL_ARR_OP_ZERO}, /* 15% = H5FL_ARR_OP_ZERO */ + {150, H5FL_ARR_OP_FILL1}, /* 15% = H5FL_ARR_OP_FILL1 */ + {150, H5FL_ARR_OP_FILL2}, /* 15% = H5FL_ARR_OP_FILL2 */ + {150, H5FL_ARR_OP_FILL3}, /* 15% = H5FL_ARR_OP_FILL3 */ + {0, H5FL_ARR_OP_FREE}, /* 0% = H5FL_ARR_OP_FREE */ +}; + /* Operation odds when token array is empty */ /* (Must sum to 1000 (i.e. 100%) */ static const h5fl_reg_test_op_odds h5fl_reg_empty_ops_odds[] = { @@ -455,6 +620,19 @@ static const h5fl_blk_test_op_odds h5fl_blk_empty_ops_odds[] = { {0, H5FL_BLK_OP_FREE}, /* 0% = H5FL_BLK_OP_FREE */ }; +/* Operation odds when token array is empty */ +/* (Must sum to 1000 (i.e. 100%) */ +static const h5fl_arr_test_op_odds h5fl_arr_empty_ops_odds[] = { + {500, H5FL_ARR_OP_MALLOC}, /* 50% = H5FL_ARR_OP_MALLOC */ + {500, H5FL_ARR_OP_CALLOC}, /* 50% = H5FL_ARR_OP_CALLOC */ + {0, H5FL_ARR_OP_REALLOC}, /* 0% = H5FL_ARR_OP_REALLOC */ + {0, H5FL_ARR_OP_ZERO}, /* 0% = H5FL_ARR_OP_ZERO */ + {0, H5FL_ARR_OP_FILL1}, /* 0% = H5FL_ARR_OP_FILL1 */ + {0, H5FL_ARR_OP_FILL2}, /* 0% = H5FL_ARR_OP_FILL2 */ + {0, H5FL_ARR_OP_FILL3}, /* 0% = H5FL_ARR_OP_FILL3 */ + {0, H5FL_ARR_OP_FREE}, /* 0% = H5FL_ARR_OP_FREE */ +}; + static unsigned get_new_h5fl_reg_token(h5fl_reg_test_token *tokens, unsigned *next_token) { @@ -515,6 +693,26 @@ get_new_h5fl_blk_token(h5fl_blk_test_token *tokens, unsigned *next_token) abort(); } +static unsigned +get_new_h5fl_arr_token(h5fl_arr_test_token *tokens, unsigned *next_token) +{ + unsigned curr_pos = *next_token; + unsigned start_pos = curr_pos; + + do { + /* Check for empty position */ + if (NULL == tokens[curr_pos].val) { + *next_token = (curr_pos + 1) % MAX_TOKENS; + return curr_pos; + } + + curr_pos = (curr_pos + 1) % MAX_TOKENS; + } while (curr_pos != start_pos); + + assert(curr_pos == start_pos && "Can't find empty position for new token"); + abort(); +} + static h5fl_reg_test_op_code get_new_h5fl_reg_op(const h5fl_reg_test_op_odds *op_odds) { @@ -563,6 +761,22 @@ get_new_h5fl_blk_op(const h5fl_blk_test_op_odds *op_odds) return op_odds[idx].op_code; } +static h5fl_arr_test_op_code +get_new_h5fl_arr_op(const h5fl_arr_test_op_odds *op_odds) +{ + unsigned idx; + unsigned rng; + + idx = 0; + rng = (unsigned)h5_local_rand() % 1000; + while (0 == op_odds[idx].odds || rng > op_odds[idx].odds) { + rng -= op_odds[idx].odds; + idx++; + } + + return op_odds[idx].op_code; +} + static unsigned get_active_h5fl_reg_token(h5fl_reg_test_token *tokens, unsigned num_possible_tokens) { @@ -620,6 +834,25 @@ get_active_h5fl_blk_token(h5fl_blk_test_token *tokens, unsigned num_possible_tok abort(); } +static unsigned +get_active_h5fl_arr_token(h5fl_arr_test_token *tokens, unsigned num_possible_tokens) +{ + unsigned curr_pos; + unsigned start_pos; + + start_pos = curr_pos = (unsigned)h5_local_rand() % num_possible_tokens; + do { + /* Check for active position */ + if (NULL != tokens[curr_pos].val) + return curr_pos; + + curr_pos = (curr_pos + 1) % num_possible_tokens; + } while (curr_pos != start_pos); + + assert(curr_pos == start_pos && "Can't find active token"); + abort(); +} + #if 0 static void print_h5fl_reg_vector(h5fl_reg_test_vector *vector, h5fl_reg_test_token *tokens) @@ -1093,6 +1326,129 @@ init_h5fl_blk_vector(unsigned vec_size, h5fl_blk_test_vector *vector, unsigned n assert(0 == num_active_tokens); } +static void +init_h5fl_arr_vector(unsigned vec_size, h5fl_arr_test_vector *vector, unsigned num_tokens, + h5fl_arr_test_token *tokens) +{ + unsigned num_active_tokens = 0; /* # of active tokens at any position in the test vector execution */ + unsigned curr_alloc_token; /* Current position for allocating tokens */ + unsigned pos; /* Current position in the test vector */ + bool tokens_wrapped = false; + + /* Allocate the test vector */ + vector->vec_size = vec_size; + vector->op_vector = calloc(vec_size, sizeof(h5fl_arr_test_op)); + CHECK_PTR(vector->op_vector, "calloc"); + + /* Fiil the test vector, leaving room to free active tokens */ + pos = 0; + curr_alloc_token = 0; + while (pos < (vec_size - num_active_tokens)) { + h5fl_arr_test_op_code op_code; + + /* Check for active tokens */ + /* (Also must have enough room for both alloc & free operations) */ + if (0 == num_active_tokens && pos < (vec_size - 2)) + op_code = get_new_h5fl_arr_op(h5fl_arr_empty_ops_odds); + else { + /* Don't create new tokens when there won't be enough room in the + * vector for both the alloc & free operations. + */ + if (pos > ((vec_size - num_active_tokens) - 2)) + op_code = get_new_h5fl_arr_op(h5fl_arr_vec_almost_full_ops_odds); + /* Don't create new tokens when the token array is full */ + else if (num_tokens == num_active_tokens) + op_code = get_new_h5fl_arr_op(h5fl_arr_full_ops_odds); + else + op_code = get_new_h5fl_arr_op(h5fl_arr_all_ops_odds); + } + + /* Set op code */ + vector->op_vector[pos].op_code = op_code; + + /* Set up specific parameters for each op code */ + switch (op_code) { + case H5FL_ARR_OP_MALLOC: + case H5FL_ARR_OP_CALLOC: { + unsigned prev_alloc_token = curr_alloc_token; + unsigned type_idx; + unsigned new_token; + + /* RNG type to allocate */ + + type_idx = (unsigned)h5_local_rand() % (unsigned)NELMTS(h5fl_arr_test_types); + new_token = get_new_h5fl_arr_token(tokens, &curr_alloc_token); + vector->op_vector[pos].token = &tokens[new_token]; + vector->op_vector[pos].param.type_idx = type_idx; + + /* Mark token as used */ + tokens[new_token].val = (void *)(~(uintptr_t)NULL); + + /* Increment # of active tokens */ + num_active_tokens++; + + /* Check for tokens wrapping */ + if (curr_alloc_token < prev_alloc_token) + tokens_wrapped = true; + } break; + + case H5FL_ARR_OP_REALLOC: { + unsigned token_idx; + + token_idx = get_active_h5fl_arr_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + vector->op_vector[pos].param.rng_size = (unsigned)h5_local_rand(); + } break; + + case H5FL_ARR_OP_ZERO: + case H5FL_ARR_OP_FILL1: + case H5FL_ARR_OP_FILL2: + case H5FL_ARR_OP_FILL3: + case H5FL_BLK_OP_FREE: { + unsigned token_idx; + + token_idx = get_active_h5fl_arr_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + + if (H5FL_ARR_OP_FREE == op_code) { + /* Mark token as free */ + tokens[token_idx].val = NULL; + + /* Decrement # of active tokens */ + num_active_tokens--; + } + } break; + + default: + assert(0 && "Invalid op code"); + abort(); + } + + pos++; + } + + /* Fill remainder of test vector with free operations */ + while (pos < vec_size) { + unsigned token_idx; + + /* Set op code */ + vector->op_vector[pos].op_code = H5FL_ARR_OP_FREE; + + token_idx = get_active_h5fl_arr_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); + vector->op_vector[pos].token = &tokens[token_idx]; + + /* Mark token as free */ + tokens[token_idx].val = NULL; + + /* Decrement # of active tokens */ + num_active_tokens--; + + pos++; + } + + assert(0 == num_active_tokens); +} + static inline unsigned validate_h5fl_reg_token(const h5fl_reg_test_token *token) { @@ -1240,6 +1596,56 @@ validate_h5fl_blk_token(const h5fl_blk_test_token *token) return (0); } +static inline unsigned +validate_h5fl_arr_token(const h5fl_arr_test_token *token) +{ + unsigned char *v = (unsigned char *)token->val; + unsigned u; + + switch (token->state) { + case H5FL_ARR_ST_UNINIT: + break; + + case H5FL_ARR_ST_ZERO: + for (u = 0; u < token->curr_size; u++) { + VERIFY(v[u], 0, "H5FL_ARR_ST_ZERO"); + if (0 != v[u]) + return (1); + } + break; + + case H5FL_ARR_ST_FILL1: + for (u = 0; u < token->curr_size; u++) { + VERIFY(v[u], 1, "H5FL_ARR_ST_FILL1"); + if (1 != v[u]) + return (1); + } + break; + + case H5FL_ARR_ST_FILL2: + for (u = 0; u < token->curr_size; u++) { + VERIFY(v[u], 2, "H5FL_ARR_ST_FILL2"); + if (2 != v[u]) + return (1); + } + break; + + case H5FL_ARR_ST_FILL3: + for (u = 0; u < token->curr_size; u++) { + VERIFY(v[u], 3, "H5FL_ARR_ST_FILL3"); + if (3 != v[u]) + return (1); + } + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } + + return (0); +} + static unsigned run_h5fl_reg_vector(h5fl_reg_test_vector *vector) { @@ -1581,6 +1987,153 @@ run_h5fl_blk_vector(h5fl_blk_test_vector *vector) return (0); } +static void +fill_h5fl_arr_vector(h5fl_arr_test_token *token) +{ + switch (token->state) { + case H5FL_ARR_ST_UNINIT: + break; + + case H5FL_ARR_ST_ZERO: + memset(token->val, 0, token->curr_size); + break; + + case H5FL_ARR_ST_FILL1: + memset(token->val, 1, token->curr_size); + break; + + case H5FL_ARR_ST_FILL2: + memset(token->val, 2, token->curr_size); + break; + + case H5FL_ARR_ST_FILL3: + memset(token->val, 3, token->curr_size); + break; + + default: + assert(0 && "Invalid state for token"); + abort(); + } +} + +static unsigned +run_h5fl_arr_vector(h5fl_arr_test_vector *vector) +{ + /* Execute test vector */ + for (unsigned u = 0; u < vector->vec_size; u++) { + switch (vector->op_vector[u].op_code) { + case H5FL_ARR_OP_MALLOC: + vector->op_vector[u].token->val = + H5FL_arr_malloc(h5fl_arr_test_types[vector->op_vector[u].param.type_idx].free_list, + h5fl_arr_test_types[vector->op_vector[u].param.type_idx].max_size); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_arr_malloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->curr_size = + h5fl_arr_test_types[vector->op_vector[u].param.type_idx].max_size; + vector->op_vector[u].token->state = H5FL_ARR_ST_UNINIT; + break; + + case H5FL_ARR_OP_CALLOC: + vector->op_vector[u].token->val = + H5FL_arr_calloc(h5fl_arr_test_types[vector->op_vector[u].param.type_idx].free_list, + h5fl_arr_test_types[vector->op_vector[u].param.type_idx].max_size); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_arr_calloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; + vector->op_vector[u].token->curr_size = + h5fl_arr_test_types[vector->op_vector[u].param.type_idx].max_size; + vector->op_vector[u].token->state = H5FL_ARR_ST_ZERO; + break; + + case H5FL_ARR_OP_REALLOC: { + unsigned new_size; + unsigned prev_size; + + /* Choose new size for token's buffer */ + new_size = 1 + (vector->op_vector[u].param.rng_size % + h5fl_arr_test_types[vector->op_vector[u].token->type_idx].max_size); + + /* Validate current buffer */ + if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_arr_token(vector->op_vector[u].token)) + return (1); + + /* Reallocate buffer */ + vector->op_vector[u].token->val = + H5FL_arr_realloc(h5fl_arr_test_types[vector->op_vector[u].token->type_idx].free_list, + vector->op_vector[u].token->val, new_size); + CHECK_PTR(vector->op_vector[u].token->val, "H5FL_arr_realloc"); + if (NULL == vector->op_vector[u].token->val) + return (1); + + /* Update size & value for buffer */ + prev_size = vector->op_vector[u].token->curr_size; + vector->op_vector[u].token->curr_size = new_size; + if (new_size > prev_size) + fill_h5fl_arr_vector(vector->op_vector[u].token); + } break; + + case H5FL_ARR_OP_ZERO: + if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_arr_token(vector->op_vector[u].token)) + return (1); + if (H5FL_ARR_ST_ZERO != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_ARR_ST_ZERO; + memset(vector->op_vector[u].token->val, 0, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_ARR_OP_FILL1: + if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_arr_token(vector->op_vector[u].token)) + return (1); + if (H5FL_ARR_ST_FILL1 != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_ARR_ST_FILL1; + memset(vector->op_vector[u].token->val, 1, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_ARR_OP_FILL2: + if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_arr_token(vector->op_vector[u].token)) + return (1); + if (H5FL_ARR_ST_FILL2 != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_ARR_ST_FILL2; + memset(vector->op_vector[u].token->val, 2, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_ARR_OP_FILL3: + if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_arr_token(vector->op_vector[u].token)) + return (1); + if (H5FL_ARR_ST_FILL3 != vector->op_vector[u].token->state) { + vector->op_vector[u].token->state = H5FL_ARR_ST_FILL3; + memset(vector->op_vector[u].token->val, 3, vector->op_vector[u].token->curr_size); + } + break; + + case H5FL_ARR_OP_FREE: + if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state) + if (0 != validate_h5fl_arr_token(vector->op_vector[u].token)) + return (1); + H5FL_arr_free(h5fl_arr_test_types[vector->op_vector[u].token->type_idx].free_list, + vector->op_vector[u].token->val); + vector->op_vector[u].token->val = NULL; + break; + + default: + assert(0 && "Invalid op code"); + abort(); + } + } + + return (0); +} + static H5TS_THREAD_RETURN_TYPE thread_h5fl_reg(void *_vectors) { @@ -1882,6 +2435,81 @@ test_h5fl_blk(void) } } +static H5TS_THREAD_RETURN_TYPE +thread_h5fl_arr(void *_vectors) +{ + h5fl_arr_test_vector *vectors = (h5fl_arr_test_vector *)_vectors; + unsigned errors = 0; + H5TS_THREAD_RETURN_TYPE ret_value = (H5TS_THREAD_RETURN_TYPE)0; + + /* Randomly run a number of vectors */ + for (unsigned u = 0; u < NUM_ITERS_PER_THREAD; u++) { + unsigned rng = (unsigned)h5_local_rand() % NUM_VECTORS; + + /* Run the test vector */ + errors += run_h5fl_arr_vector(&vectors[rng]); + } + + if (errors > 0) + ret_value = (H5TS_THREAD_RETURN_TYPE)1; + + return ret_value; +} + +/* 'array' H5FL test vectors */ +static h5fl_arr_test_vector *h5fl_arr_vectors[NUM_THREADS]; + +static void +test_h5fl_arr(void) +{ + h5fl_arr_test_token *tokens[NUM_THREADS]; /* Test tokens */ + H5TS_thread_t threads[NUM_THREADS]; + herr_t result; + + /* Output message about test being performed */ + MESSAGE(7, ("Testing 'array' H5FL operations\n")); + + /* Initialize the test vectors */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + /* Allocate the test tokens */ + tokens[u] = calloc(MAX_TOKENS, sizeof(h5fl_arr_test_token)); + CHECK_PTR(tokens[u], "calloc"); + + /* Initialize the test vectors */ + h5fl_arr_vectors[u] = calloc(NUM_VECTORS, sizeof(h5fl_arr_test_vector)); + CHECK_PTR(h5fl_arr_vectors[u], "calloc"); + + for (unsigned v = 0; v < NUM_VECTORS; v++) + init_h5fl_arr_vector(NUM_TEST_OPS, &h5fl_arr_vectors[u][v], MAX_TOKENS, tokens[u]); + } + + /* Create threads and have them execute the vector */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + result = H5TS_thread_create(&threads[u], thread_h5fl_arr, h5fl_arr_vectors[u]); + CHECK_I(result, "H5TS_thread_create"); + } + + /* Wait for all threads */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + H5TS_THREAD_RETURN_TYPE thread_ret = (H5TS_THREAD_RETURN_TYPE)0; + + /* Join thread */ + result = H5TS_thread_join(threads[u], &thread_ret); + CHECK_I(result, "H5TS_thread_join"); + + /* Verify no errors from thread */ + VERIFY(thread_ret, (H5TS_THREAD_RETURN_TYPE)0, "error in thread"); + } + + /* Free test vectors & tokens */ + for (unsigned u = 0; u < NUM_THREADS; u++) { + free(tokens[u]); + for (unsigned v = 0; v < NUM_VECTORS; v++) + free(h5fl_arr_vectors[u][v].op_vector); + free(h5fl_arr_vectors[u]); + } +} + /* ********************************************************************** * Test H5FL package @@ -1900,6 +2528,7 @@ tts_h5fl(const void H5_ATTR_UNUSED *params) test_h5fl_reg(); test_h5fl_fac(); test_h5fl_blk(); + test_h5fl_arr(); } /* end tts_h5fl() */ #endif /*H5_HAVE_THREADS*/ From 8ccdcab1b7b9f891cc36a3a1922618aefb4b1797 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 02:09:36 +0000 Subject: [PATCH 8/8] Committing clang-format changes --- test/ttsafe_h5fl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/ttsafe_h5fl.c b/test/ttsafe_h5fl.c index 0963337cc8b..a4fcdf1e854 100644 --- a/test/ttsafe_h5fl.c +++ b/test/ttsafe_h5fl.c @@ -197,7 +197,7 @@ typedef struct { typedef struct { H5FL_arr_head_t *free_list; - unsigned max_size; + unsigned max_size; } h5fl_arr_type_info; /* Array of all the 'regular' free lists & info */ @@ -1396,7 +1396,7 @@ init_h5fl_arr_vector(unsigned vec_size, h5fl_arr_test_vector *vector, unsigned n unsigned token_idx; token_idx = get_active_h5fl_arr_token(tokens, tokens_wrapped ? num_tokens : curr_alloc_token); - vector->op_vector[pos].token = &tokens[token_idx]; + vector->op_vector[pos].token = &tokens[token_idx]; vector->op_vector[pos].param.rng_size = (unsigned)h5_local_rand(); } break; @@ -1600,7 +1600,7 @@ static inline unsigned validate_h5fl_arr_token(const h5fl_arr_test_token *token) { unsigned char *v = (unsigned char *)token->val; - unsigned u; + unsigned u; switch (token->state) { case H5FL_ARR_ST_UNINIT: @@ -2032,7 +2032,7 @@ run_h5fl_arr_vector(h5fl_arr_test_vector *vector) vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; vector->op_vector[u].token->curr_size = h5fl_arr_test_types[vector->op_vector[u].param.type_idx].max_size; - vector->op_vector[u].token->state = H5FL_ARR_ST_UNINIT; + vector->op_vector[u].token->state = H5FL_ARR_ST_UNINIT; break; case H5FL_ARR_OP_CALLOC: @@ -2045,7 +2045,7 @@ run_h5fl_arr_vector(h5fl_arr_test_vector *vector) vector->op_vector[u].token->type_idx = vector->op_vector[u].param.type_idx; vector->op_vector[u].token->curr_size = h5fl_arr_test_types[vector->op_vector[u].param.type_idx].max_size; - vector->op_vector[u].token->state = H5FL_ARR_ST_ZERO; + vector->op_vector[u].token->state = H5FL_ARR_ST_ZERO; break; case H5FL_ARR_OP_REALLOC: { @@ -2054,7 +2054,7 @@ run_h5fl_arr_vector(h5fl_arr_test_vector *vector) /* Choose new size for token's buffer */ new_size = 1 + (vector->op_vector[u].param.rng_size % - h5fl_arr_test_types[vector->op_vector[u].token->type_idx].max_size); + h5fl_arr_test_types[vector->op_vector[u].token->type_idx].max_size); /* Validate current buffer */ if (H5FL_ARR_ST_UNINIT != vector->op_vector[u].token->state)