diff options
Diffstat (limited to 'testpar')
-rw-r--r-- | testpar/t_cache.c | 756 |
1 files changed, 706 insertions, 50 deletions
diff --git a/testpar/t_cache.c b/testpar/t_cache.c index 8b119b8..3bacb8e 100644 --- a/testpar/t_cache.c +++ b/testpar/t_cache.c @@ -224,15 +224,21 @@ int data_index[NUM_DATA_ENTRIES]; * *****************************************************************************/ +#define DO_WRITE_REQ_ACK FALSE +#define DO_SYNC_AFTER_WRITE TRUE + #define WRITE_REQ_CODE 0 -#define READ_REQ_CODE 1 -#define READ_REQ_REPLY_CODE 2 -#define DONE_REQ_CODE 3 -#define MAX_REQ_CODE 3 +#define WRITE_REQ_ACK_CODE 1 +#define READ_REQ_CODE 2 +#define READ_REQ_REPLY_CODE 3 +#define SYNC_REQ_CODE 4 +#define SYNC_ACK_CODE 5 +#define DONE_REQ_CODE 6 +#define MAX_REQ_CODE 6 #define MSSG_MAGIC 0x1248 -typedef struct mssg_t +struct mssg_t { int req; int src; @@ -270,13 +276,14 @@ void init_data(void); /* test coodination related functions */ int do_express_test(void); +void do_sync(void); int get_max_nerrors(void); /* mssg xfer related functions */ -hbool_t recv_mssg(struct mssg_t *mssg_ptr); -hbool_t send_mssg(struct mssg_t *mssg_ptr); +hbool_t recv_mssg(struct mssg_t *mssg_ptr, int mssg_tag_offset); +hbool_t send_mssg(struct mssg_t *mssg_ptr, hbool_t add_req_to_tag); hbool_t setup_derived_types(void); hbool_t takedown_derived_types(void); @@ -285,6 +292,7 @@ hbool_t takedown_derived_types(void); hbool_t server_main(void); hbool_t serve_read_request(struct mssg_t * mssg_ptr); +hbool_t serve_sync_request(struct mssg_t * mssg_ptr); hbool_t serve_write_request(struct mssg_t * mssg_ptr); @@ -336,6 +344,9 @@ void lock_and_unlock_random_entry(H5C_t * cache_ptr, H5F_t * file_ptr, void lock_entry(H5C_t * cache_ptr, H5F_t * file_ptr, int32_t idx); void mark_pinned_entry_dirty(H5C_t * cache_ptr, H5F_t * file_ptr, int32_t idx, hbool_t size_changed, size_t new_size); +void mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr, + H5F_t * file_ptr, + int32_t idx); void pin_entry(H5C_t * cache_ptr, H5F_t * file_ptr, int32_t idx, hbool_t global, hbool_t dirty); void rename_entry(H5C_t * cache_ptr, H5F_t * file_ptr, @@ -357,6 +368,7 @@ hbool_t smoke_check_1(void); hbool_t smoke_check_2(void); hbool_t smoke_check_3(void); hbool_t smoke_check_4(void); +hbool_t smoke_check_5(void); /*****************************************************************************/ @@ -648,7 +660,7 @@ addr_to_datum_index(haddr_t base_addr) /***************************************************************************** * - * Function: init_data_array() + * Function: init_data() * * Purpose: Initialize the data array, from which cache entries are * loaded. @@ -777,6 +789,85 @@ do_express_test(void) /***************************************************************************** * + * Function: do_sync() + * + * Purpose: Ensure that all messages sent by this process have been + * processed before proceeding. + * + * Do this by exchanging sync req / sync ack messages with + * the server. + * + * Do nothing if nerrors is greater than zero. + * + * Return: void + * + * Programmer: JRM -- 5/10/06 + * + * Modifications: + * + * None. + * + *****************************************************************************/ + +void +do_sync(void) +{ + const char * fcn_name = "do_sync()"; + + herr_t ret_value = SUCCEED; + struct mssg_t mssg; + + if ( nerrors <= 0 ) { + + /* compose the message */ + mssg.req = SYNC_REQ_CODE; + mssg.src = world_mpi_rank; + mssg.dest = world_server_mpi_rank; + mssg.mssg_num = -1; /* set by send function */ + mssg.base_addr = 0; + mssg.len = 0; + mssg.ver = 0; + mssg.magic = MSSG_MAGIC; + + if ( ! send_mssg(&mssg, FALSE) ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: send_mssg() failed.\n", + world_mpi_rank, fcn_name); + } + } + } + + if ( nerrors <= 0 ) { + + if ( ! recv_mssg(&mssg, SYNC_ACK_CODE) ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: recv_mssg() failed.\n", + world_mpi_rank, fcn_name); + } + } else if ( ( mssg.req != SYNC_ACK_CODE ) || + ( mssg.src != world_server_mpi_rank ) || + ( mssg.dest != world_mpi_rank ) || + ( mssg.magic != MSSG_MAGIC ) ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: Bad data in sync ack.\n", + world_mpi_rank, fcn_name); + } + } + } + + return; + +} /* do_sync() */ + + +/***************************************************************************** + * * Function: get_max_nerrors() * * Purpose: Do an MPI_Allreduce to obtain the maximum value of nerrors @@ -843,34 +934,42 @@ get_max_nerrors(void) * * Modifications: * - * None. + * JRM -- 5/10/06 + * Added mssg_tag_offset parameter and supporting code. * *****************************************************************************/ #define CACHE_TEST_TAG 99 /* different from any used by the library */ hbool_t -recv_mssg(struct mssg_t *mssg_ptr) +recv_mssg(struct mssg_t *mssg_ptr, + int mssg_tag_offset) { const char * fcn_name = "recv_mssg()"; hbool_t success = TRUE; + int mssg_tag = CACHE_TEST_TAG; int result; MPI_Status status; - if ( mssg_ptr == NULL ) { + if ( ( mssg_ptr == NULL ) || + ( mssg_tag_offset < 0 ) || + ( mssg_tag_offset> MAX_REQ_CODE ) ) { nerrors++; success = FALSE; if ( verbose ) { - HDfprintf(stdout, "%d:%s: NULL mssg_ptr on entry.\n", + HDfprintf(stdout, "%d:%s: bad param(s) on entry.\n", world_mpi_rank, fcn_name); } + } else { + + mssg_tag += mssg_tag_offset; } if ( success ) { result = MPI_Recv((void *)mssg_ptr, 1, mpi_mssg_t, MPI_ANY_SOURCE, - CACHE_TEST_TAG, world_mpi_comm, &status); + mssg_tag, world_mpi_comm, &status); if ( result != MPI_SUCCESS ) { @@ -922,15 +1021,18 @@ recv_mssg(struct mssg_t *mssg_ptr) * * Modifications: * - * None. + * JRM -- 5/10/06 + * Added the add_req_to_tag parameter and supporting code. * *****************************************************************************/ hbool_t -send_mssg(struct mssg_t *mssg_ptr) +send_mssg(struct mssg_t *mssg_ptr, + hbool_t add_req_to_tag) { const char * fcn_name = "send_mssg()"; hbool_t success = TRUE; + int mssg_tag = CACHE_TEST_TAG; int result; static long mssg_num = 0; @@ -955,8 +1057,13 @@ send_mssg(struct mssg_t *mssg_ptr) mssg_ptr->mssg_num = mssg_num++; + if ( add_req_to_tag ) { + + mssg_tag += mssg_ptr->req; + } + result = MPI_Send((void *)mssg_ptr, 1, mpi_mssg_t, - mssg_ptr->dest, CACHE_TEST_TAG, world_mpi_comm); + mssg_ptr->dest, mssg_tag, world_mpi_comm); if ( result != MPI_SUCCESS ) { @@ -1134,7 +1241,8 @@ takedown_derived_types(void) * * Modifications: * - * None. + * JRM -- 5/10/06 + * Updated for sync message. * *****************************************************************************/ @@ -1160,7 +1268,7 @@ server_main(void) while ( ( success ) && ( ! done ) ) { - success = recv_mssg(&mssg); + success = recv_mssg(&mssg, 0); if ( success ) { @@ -1170,6 +1278,11 @@ server_main(void) success = serve_write_request(&mssg); break; + case WRITE_REQ_ACK_CODE: + success = FALSE; + HDfprintf(stdout, "%s: Received write ack?!?.\n", fcn_name); + break; + case READ_REQ_CODE: success = serve_read_request(&mssg); break; @@ -1180,6 +1293,16 @@ server_main(void) fcn_name); break; + case SYNC_REQ_CODE: + success = serve_sync_request(&mssg); + break; + + case SYNC_ACK_CODE: + success = FALSE; + HDfprintf(stdout, "%s: Received sync ack?!?.\n", + fcn_name); + break; + case DONE_REQ_CODE: done_count++; /* HDfprintf(stdout, "%d:%s: done_count = %d.\n", @@ -1280,9 +1403,11 @@ serve_read_request(struct mssg_t * mssg_ptr) success = FALSE; if ( verbose ) { HDfprintf(stdout, - "%d:%s: proc %d read invalid entry. base_addr = %a.\n", + "%d:%s: proc %d read invalid entry. idx/base_addr = %d/%a.\n", world_mpi_rank, fcn_name, - mssg_ptr->src, data[target_index].base_addr); + mssg_ptr->src, target_index, + target_index, + data[target_index].base_addr); } } else { @@ -1300,7 +1425,7 @@ serve_read_request(struct mssg_t * mssg_ptr) if ( success ) { - success = send_mssg(&reply); + success = send_mssg(&reply, TRUE); } return(success); @@ -1310,6 +1435,74 @@ serve_read_request(struct mssg_t * mssg_ptr) /***************************************************************************** * + * Function: serve_sync_request() + * + * Purpose: Serve a sync request. + * + * The function accepts a pointer to an instance of struct + * mssg_t as input. If all sanity checks pass, it sends a + * sync ack to the requesting process. + * + * This service exist to allow the sending process to ensure + * that all previous messages have been processed before + * proceeding. + * + * Return: Success: TRUE + * + * Failure: FALSE + * + * Programmer: JRM -- 5/10/06 + * + * Modifications: + * + * None. + * + *****************************************************************************/ + +hbool_t +serve_sync_request(struct mssg_t * mssg_ptr) +{ + const char * fcn_name = "serve_sync_request()"; + hbool_t success = TRUE; + struct mssg_t reply; + + if ( ( mssg_ptr == NULL ) || + ( mssg_ptr->req != SYNC_REQ_CODE ) || + ( mssg_ptr->magic != MSSG_MAGIC ) ) { + + nerrors++; + success = FALSE; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: Bad mssg on entry.\n", + world_mpi_rank, fcn_name); + } + } + + if ( success ) { + + /* compose the reply message */ + reply.req = SYNC_ACK_CODE; + reply.src = world_mpi_rank; + reply.dest = mssg_ptr->src; + reply.mssg_num = -1; /* set by send function */ + reply.base_addr = 0; + reply.len = 0; + reply.ver = 0; + reply.magic = MSSG_MAGIC; + } + + if ( success ) { + + success = send_mssg(&reply, TRUE); + } + + return(success); + +} /* serve_sync_request() */ + + +/***************************************************************************** + * * Function: serve_write_request() * * Purpose: Serve a write request. @@ -1327,7 +1520,10 @@ serve_read_request(struct mssg_t * mssg_ptr) * * Modifications: * - * None. + * JRM -- 5/9/06 + * Added code supporting a write ack message. This is a + * speculative fix to a bug observed on Cobalt. If it + * doesn't work, it will help narrow down the possibilities. * *****************************************************************************/ @@ -1339,6 +1535,9 @@ serve_write_request(struct mssg_t * mssg_ptr) int target_index; int new_ver_num; haddr_t target_addr; +#if DO_WRITE_REQ_ACK + struct mssg_t reply; +#endif /* DO_WRITE_REQ_ACK */ if ( ( mssg_ptr == NULL ) || ( mssg_ptr->req != WRITE_REQ_CODE ) || @@ -1396,8 +1595,27 @@ serve_write_request(struct mssg_t * mssg_ptr) if ( success ) { + /* process the write */ data[target_index].ver = new_ver_num; data[target_index].valid = TRUE; + +#if DO_WRITE_REQ_ACK + + /* compose the reply message */ + reply.req = WRITE_REQ_ACK_CODE; + reply.src = world_mpi_rank; + reply.dest = mssg_ptr->src; + reply.mssg_num = -1; /* set by send function */ + reply.base_addr = data[target_index].base_addr; + reply.len = data[target_index].len; + reply.ver = data[target_index].ver; + reply.magic = MSSG_MAGIC; + + /* and send it */ + success = send_mssg(&reply, TRUE); + +#endif /* DO_WRITE_REQ_ACK */ + } return(success); @@ -1531,6 +1749,12 @@ destroy_datum(H5F_t UNUSED * f, * * Modifications: * + * JRM -- 5/9/06 + * Added code to receive the write request ack messages + * from the server. This is part of a speculative fix to + * a bug spotted on Cobalt. If it doesn't fix the problem, + * it will narrow down the possibilities. + * *------------------------------------------------------------------------- */ @@ -1585,7 +1809,7 @@ flush_datum(H5F_t *f, mssg.ver = entry_ptr->ver; mssg.magic = MSSG_MAGIC; - if ( ! send_mssg(&mssg) ) { + if ( ! send_mssg(&mssg, FALSE) ) { nerrors++; ret_value = FAIL; @@ -1602,6 +1826,37 @@ flush_datum(H5F_t *f, } } +#if DO_WRITE_REQ_ACK + + if ( ( ret_value == SUCCEED ) && ( entry_ptr->header.is_dirty ) ) { + + if ( ! recv_mssg(&mssg, WRITE_REQ_ACK_CODE) ) { + + nerrors++; + ret_value = FAIL; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: recv_mssg() failed.\n", + world_mpi_rank, fcn_name); + } + } else if ( ( mssg.req != WRITE_REQ_ACK_CODE ) || + ( mssg.src != world_server_mpi_rank ) || + ( mssg.dest != world_mpi_rank ) || + ( mssg.base_addr != entry_ptr->base_addr ) || + ( mssg.len != entry_ptr->len ) || + ( mssg.ver != entry_ptr->ver ) || + ( mssg.magic != MSSG_MAGIC ) ) { + + nerrors++; + ret_value = FAIL; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: Bad data in write req ack.\n", + world_mpi_rank, fcn_name); + } + } + } + +#endif /* DO_WRITE_REQ_ACK */ + if ( ret_value == SUCCEED ) { if ( dest ) { @@ -1673,7 +1928,7 @@ load_datum(H5F_t UNUSED *f, mssg.ver = 0; /* bogus -- should be corrected by server */ mssg.magic = MSSG_MAGIC; - if ( ! send_mssg(&mssg) ) { + if ( ! send_mssg(&mssg, FALSE) ) { nerrors++; success = FALSE; @@ -1685,7 +1940,7 @@ load_datum(H5F_t UNUSED *f, if ( success ) { - if ( ! recv_mssg(&mssg) ) { + if ( ! recv_mssg(&mssg, READ_REQ_REPLY_CODE) ) { nerrors++; success = FALSE; @@ -1712,6 +1967,58 @@ load_datum(H5F_t UNUSED *f, HDfprintf(stdout, "%d:%s: Bad data in read req reply.\n", world_mpi_rank, fcn_name); } +#if 0 /* This has been useful debugging code -- keep it for now. */ + if ( mssg.req != READ_REQ_REPLY_CODE ) { + + HDfprintf(stdout, "%d:%s: mssg.req != READ_REQ_REPLY_CODE.\n", + world_mpi_rank, fcn_name); + HDfprintf(stdout, "%d:%s: mssg.req = %d.\n", + world_mpi_rank, fcn_name, (int)(mssg.req)); + } + + if ( mssg.src != world_server_mpi_rank ) { + + HDfprintf(stdout, "%d:%s: mssg.src != world_server_mpi_rank.\n", + world_mpi_rank, fcn_name); + } + + if ( mssg.dest != world_mpi_rank ) { + + HDfprintf(stdout, "%d:%s: mssg.dest != world_mpi_rank.\n", + world_mpi_rank, fcn_name); + } + + if ( mssg.base_addr != entry_ptr->base_addr ) { + + HDfprintf(stdout, + "%d:%s: mssg.base_addr != entry_ptr->base_addr.\n", + world_mpi_rank, fcn_name); + HDfprintf(stdout, "%d:%s: mssg.base_addr = %a.\n", + world_mpi_rank, fcn_name, mssg.base_addr); + HDfprintf(stdout, "%d:%s: entry_ptr->base_addr = %a.\n", + world_mpi_rank, fcn_name, entry_ptr->base_addr); + } + + if ( mssg.len != entry_ptr->len ) { + + HDfprintf(stdout, "%d:%s: mssg.len != entry_ptr->len.\n", + world_mpi_rank, fcn_name); + HDfprintf(stdout, "%d:%s: mssg.len = %a.\n", + world_mpi_rank, fcn_name, mssg.len); + } + + if ( mssg.ver < entry_ptr->ver ) { + + HDfprintf(stdout, "%d:%s: mssg.ver < entry_ptr->ver.\n", + world_mpi_rank, fcn_name); + } + + if ( mssg.magic != MSSG_MAGIC ) { + + HDfprintf(stdout, "%d:%s: mssg.magic != MSSG_MAGIC.\n", + world_mpi_rank, fcn_name); + } +#endif /* JRM */ } else { entry_ptr->ver = mssg.ver; @@ -2244,6 +2551,8 @@ lock_entry(H5C_t * cache_ptr, entry_ptr = &(data[idx]); + HDassert( ! (entry_ptr->locked) ); + cache_entry_ptr = H5AC_protect(file_ptr, -1, &(types[0]), entry_ptr->base_addr, NULL, NULL, H5AC_WRITE); @@ -2258,7 +2567,12 @@ lock_entry(H5C_t * cache_ptr, HDfprintf(stdout, "%d:%s: error in H5AC_protect().\n", world_mpi_rank, fcn_name); } - } + } else { + + entry_ptr->locked = TRUE; + + } + HDassert( ((entry_ptr->header).type)->id == DATUM_ENTRY_TYPE ); } @@ -2319,7 +2633,8 @@ mark_pinned_entry_dirty(H5C_t * cache_ptr, nerrors++; if ( verbose ) { - HDfprintf(stdout, "%d:%s: error in H5AC_mark_pinned_entry_dirty().\n", + HDfprintf(stdout, + "%d:%s: error in H5AC_mark_pinned_entry_dirty().\n", world_mpi_rank, fcn_name); } } @@ -2335,6 +2650,69 @@ mark_pinned_entry_dirty(H5C_t * cache_ptr, /***************************************************************************** + * Function: mark_pinned_or_protected_entry_dirty() + * + * Purpose: Use the H5AC_mark_pinned_or_protected_entry_dirty() call to + * mark dirty the entry indicated by the index, + * + * Do nothing if nerrors is non-zero on entry. + * + * Return: void + * + * Programmer: John Mainzer + * 5/18/06 + * + * Modifications: + * + *****************************************************************************/ + +void +mark_pinned_or_protected_entry_dirty(H5C_t * cache_ptr, + H5F_t * file_ptr, + int32_t idx) +{ + const char * fcn_name = "mark_pinned_or_protected_entry_dirty()"; + herr_t result; + struct datum * entry_ptr; + + if ( nerrors == 0 ) { + + HDassert( file_ptr ); + HDassert( cache_ptr ); + HDassert( ( 0 <= idx ) && ( idx < NUM_DATA_ENTRIES ) ); + HDassert( idx < virt_num_data_entries ); + + entry_ptr = &(data[idx]); + + HDassert ( entry_ptr->locked || entry_ptr->global_pinned ); + + (entry_ptr->ver)++; + entry_ptr->dirty = TRUE; + + result = H5AC_mark_pinned_or_protected_entry_dirty(file_ptr, + (void *)entry_ptr); + + if ( result < 0 ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: error in %s.\n", + world_mpi_rank, fcn_name, + "H5AC_mark_pinned_or_protected_entry_dirty()"); + } + } + else if ( ! ( entry_ptr->locked ) ) + { + global_dirty_pins++; + } + } + + return; + +} /* mark_pinned_or_protected_entry_dirty() */ + + +/***************************************************************************** * Function: pin_entry() * * Purpose: Pin the entry indicated by the index. @@ -2625,6 +3003,23 @@ setup_cache_for_test(hid_t * fid_ptr, } } +#if DO_SYNC_AFTER_WRITE + + if ( success ) { + + if ( H5AC_set_write_done_callback(cache_ptr, do_sync) != SUCCEED ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, + "%d:%s: H5C_set_write_done_callback failed.\n", + world_mpi_rank, fcn_name); + } + } + } + +#endif /* DO_SYNC_AFTER_WRITE */ + return(success); } /* setup_cache_for_test() */ @@ -2764,7 +3159,8 @@ setup_noblock_dxpl_id(void) * * Modifications: * - * None. + * JRM -- 5/9/06 + * Modified function to facilitate setting predefined seeds. * *****************************************************************************/ @@ -2772,23 +3168,41 @@ void setup_rand(void) { const char * fcn_name = "setup_rand()"; + hbool_t use_predefined_seeds = FALSE; + int num_predefined_seeds = 3; + unsigned predefined_seeds[3] = {18669, 89925, 12577}; unsigned seed; struct timeval tv; struct timezone tz; - if ( HDgettimeofday(&tv, &tz) != 0 ) { + if ( ( use_predefined_seeds ) && + ( world_mpi_size == num_predefined_seeds ) ) { + + HDassert( world_mpi_rank >= 0 ); + HDassert( world_mpi_rank < world_mpi_size ); + + seed = predefined_seeds[world_mpi_rank]; + HDfprintf(stdout, "%d:%s: predefined_seed = %d.\n", + world_mpi_rank, fcn_name, seed); + fflush(stdout); + HDsrand(seed); - nerrors++; - if ( verbose ) { - HDfprintf(stdout, "%d:%s: gettimeofday() failed.\n", - world_mpi_rank, fcn_name); - } } else { - seed = (unsigned)tv.tv_usec; - HDfprintf(stdout, "%d:%s: seed = %d.\n", - world_mpi_rank, fcn_name, seed); - fflush(stdout); - HDsrand(seed); + + if ( HDgettimeofday(&tv, &tz) != 0 ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: gettimeofday() failed.\n", + world_mpi_rank, fcn_name); + } + } else { + seed = (unsigned)tv.tv_usec; + HDfprintf(stdout, "%d:%s: seed = %d.\n", + world_mpi_rank, fcn_name, seed); + fflush(stdout); + HDsrand(seed); + } } return; @@ -2891,6 +3305,8 @@ unlock_entry(H5C_t * cache_ptr, entry_ptr = &(data[idx]); + HDassert( entry_ptr->locked ); + dirtied = ((flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG ); if ( dirtied ) { @@ -2913,7 +3329,11 @@ unlock_entry(H5C_t * cache_ptr, HDfprintf(stdout, "%d:%s: error in H5C_unprotect().\n", world_mpi_rank, fcn_name); } - } + } else { + + entry_ptr->locked = FALSE; + + } HDassert( ((entry_ptr->header).type)->id == DATUM_ENTRY_TYPE ); @@ -3040,7 +3460,16 @@ unpin_entry(H5C_t * cache_ptr, * * Modifications: * - * None. + * JRM -- 5/9/06 + * Added code supporting the write request ack message. This + * message was added to eliminate one possible cause of a + * bug spotted on cobalt. If this doesn't fix the problem, + * it will narrow things down a bit. + * + * JRM -- 5/10/06 + * Added call to do_sync(). This is part of an attempt to + * optimize out the slowdown caused by the addition of the + * write request ack message. * *****************************************************************************/ @@ -3085,7 +3514,7 @@ server_smoke_check(void) mssg.ver = ++(data[world_mpi_rank].ver); mssg.magic = MSSG_MAGIC; - if ( ! ( success = send_mssg(&mssg) ) ) { + if ( ! ( success = send_mssg(&mssg, FALSE) ) ) { nerrors++; if ( verbose ) { @@ -3094,6 +3523,47 @@ server_smoke_check(void) } } +#if DO_WRITE_REQ_ACK + + /* try to receive the write ack from the server */ + if ( success ) { + + success = recv_mssg(&mssg, WRITE_REQ_ACK_CODE); + + if ( ! success ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: recv_mssg() failed.\n", + world_mpi_rank, fcn_name); + } + } + } + + /* verify that we received the expected ack message */ + if ( success ) { + + if ( ( mssg.req != WRITE_REQ_ACK_CODE ) || + ( mssg.src != world_server_mpi_rank ) || + ( mssg.dest != world_mpi_rank ) || + ( mssg.base_addr != data[world_mpi_rank].base_addr ) || + ( mssg.len != data[world_mpi_rank].len ) || + ( mssg.ver != data[world_mpi_rank].ver ) || + ( mssg.magic != MSSG_MAGIC ) ) { + + success = FALSE; + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: Bad data in write req ack.\n", + world_mpi_rank, fcn_name); + } + } + } + +#endif /* DO_WRITE_REQ_ACK */ + + do_sync(); + /* compose the read message */ mssg.req = READ_REQ_CODE; mssg.src = world_mpi_rank; @@ -3106,7 +3576,7 @@ server_smoke_check(void) if ( success ) { - success = send_mssg(&mssg); + success = send_mssg(&mssg, FALSE); if ( ! success ) { @@ -3121,7 +3591,7 @@ server_smoke_check(void) /* try to receive the reply from the server */ if ( success ) { - success = recv_mssg(&mssg); + success = recv_mssg(&mssg, READ_REQ_REPLY_CODE); if ( ! success ) { @@ -3165,7 +3635,7 @@ server_smoke_check(void) if ( success ) { - success = send_mssg(&mssg); + success = send_mssg(&mssg, FALSE); if ( ! success ) { @@ -3326,7 +3796,7 @@ smoke_check_1(void) if ( success ) { - success = send_mssg(&mssg); + success = send_mssg(&mssg, FALSE); if ( ! success ) { @@ -3338,7 +3808,7 @@ smoke_check_1(void) } } } - + max_nerrors = get_max_nerrors(); if ( world_mpi_rank == 0 ) { @@ -3543,7 +4013,7 @@ smoke_check_2(void) if ( success ) { - success = send_mssg(&mssg); + success = send_mssg(&mssg, FALSE); if ( ! success ) { @@ -3864,7 +4334,7 @@ smoke_check_3(void) if ( success ) { - success = send_mssg(&mssg); + success = send_mssg(&mssg, FALSE); if ( ! success ) { @@ -4163,7 +4633,7 @@ smoke_check_4(void) if ( success ) { - success = send_mssg(&mssg); + success = send_mssg(&mssg, FALSE); if ( ! success ) { @@ -4200,6 +4670,189 @@ smoke_check_4(void) /***************************************************************************** * + * Function: smoke_check_5() + * + * Purpose: Similar to smoke check 1, but modified to verify that + * H5AC_mark_pinned_or_protected_entry_dirty() works in + * the parallel case. + * + * Return: Success: TRUE + * + * Failure: FALSE + * + * Programmer: JRM -- 5/18/06 + * + * Modifications: + * + * None. + * + *****************************************************************************/ + +hbool_t +smoke_check_5(void) +{ + const char * fcn_name = "smoke_check_5()"; + hbool_t success = TRUE; + int i; + int max_nerrors; + hid_t fid = -1; + H5F_t * file_ptr = NULL; + H5C_t * cache_ptr = NULL; + struct mssg_t mssg; + + if ( world_mpi_rank == 0 ) { + + TESTING("smoke check #5"); + } + + nerrors = 0; + init_data(); + reset_stats(); + + if ( world_mpi_rank == world_server_mpi_rank ) { + + if ( ! server_main() ) { + + /* some error occured in the server -- report failure */ + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: server_main() failed.\n", + world_mpi_rank, fcn_name); + } + } + } + else /* run the clients */ + { + if ( ! setup_cache_for_test(&fid, &file_ptr, &cache_ptr) ) { + + nerrors++; + fid = -1; + cache_ptr = NULL; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: setup_cache_for_test() failed.\n", + world_mpi_rank, fcn_name); + } + } + + for ( i = 0; i < (virt_num_data_entries / 2); i++ ) + { + insert_entry(cache_ptr, file_ptr, i, H5AC__NO_FLAGS_SET); + } + + /* flush the file so we can lock known clean entries. */ + if ( H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0 ) { + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: H5Fflush() failed.\n", + world_mpi_rank, fcn_name); + } + } + + for ( i = 0; i < (virt_num_data_entries / 4); i++ ) + { + lock_entry(cache_ptr, file_ptr, i); + + if ( i % 2 == 0 ) + { + mark_pinned_or_protected_entry_dirty(cache_ptr, file_ptr, i); + } + + unlock_entry(cache_ptr, file_ptr, i, H5AC__NO_FLAGS_SET); + } + + for ( i = (virt_num_data_entries / 2) - 1; + i >= (virt_num_data_entries / 4); + i-- ) + { + pin_entry(cache_ptr, file_ptr, i, TRUE, FALSE); + + if ( i % 2 == 0 ) + { + if ( i % 4 == 0 ) + { + mark_pinned_or_protected_entry_dirty(cache_ptr, + file_ptr, i); + } + else + { + mark_pinned_entry_dirty(cache_ptr, file_ptr, i, + FALSE, (size_t)0); + } + } + unpin_entry(cache_ptr, file_ptr, i, TRUE, FALSE, FALSE); + } + + if ( fid >= 0 ) { + + if ( ! take_down_cache(fid) ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: take_down_cache() failed.\n", + world_mpi_rank, fcn_name); + } + } + } + + /* verify that all instance of datum are back where the started + * and are clean. + */ + + for ( i = 0; i < NUM_DATA_ENTRIES; i++ ) + { + HDassert( data_index[i] == i ); + HDassert( ! (data[i].dirty) ); + } + + /* compose the done message */ + mssg.req = DONE_REQ_CODE; + mssg.src = world_mpi_rank; + mssg.dest = world_server_mpi_rank; + mssg.mssg_num = -1; /* set by send function */ + mssg.base_addr = 0; /* not used */ + mssg.len = 0; /* not used */ + mssg.ver = 0; /* not used */ + mssg.magic = MSSG_MAGIC; + + if ( success ) { + + success = send_mssg(&mssg, FALSE); + + if ( ! success ) { + + nerrors++; + if ( verbose ) { + HDfprintf(stdout, "%d:%s: send_mssg() failed on done.\n", + world_mpi_rank, fcn_name); + } + } + } + } + + max_nerrors = get_max_nerrors(); + + if ( world_mpi_rank == 0 ) { + + if ( max_nerrors == 0 ) { + + PASSED(); + + } else { + + failures++; + H5_FAILED(); + } + } + + success = ( ( success ) && ( max_nerrors == 0 ) ); + + return(success); + +} /* smoke_check_5() */ + + +/***************************************************************************** + * * Function: main() * * Purpose: Main function for the parallel cache test. @@ -4375,6 +5028,9 @@ main(int argc, char **argv) #if 1 smoke_check_4(); #endif +#if 1 + smoke_check_5(); +#endif finish: /* make sure all processes are finished before final report, cleanup |