1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/* $Source: bitbucket.org:berkeleylab/gasnet.git/tests/testcore3.c $
* Description: GASNet Active Messages conformance test
* Copyright (c) 2010, The Regents of the University of California
* Terms of use are as specified in license.txt
*/
#include <gasnetex.h>
#include <test.h>
static gex_Client_t myclient;
static gex_EP_t myep;
static gex_TM_t myteam;
static gex_Segment_t mysegment;
gex_Rank_t mynode = 0;
gex_Rank_t next = 0;
gex_Rank_t prev = 0;
void *myseg = NULL;
void *nextseg = NULL;
void *prevseg = NULL;
void *addr_tbl[] = {
(void*)NULL, /* Will become myseg */
(void*)NULL,
(void*)(uintptr_t)1,
(void*)(~(uintptr_t)0),
#if PLATFORM_ARCH_32
(void*)(uintptr_t)0x12345678
#else
(void*)(uintptr_t)0x123456789abcdefLL
#endif
};
#define NUM_ADDRS (sizeof(addr_tbl)/sizeof(addr_tbl[0]))
#define hidx_ping_medhandler 201
#define hidx_pong_medhandler 202
#define hidx_ping_longhandler 203
#define hidx_pong_longhandler 204
volatile int flag = 0;
void ping_medhandler(gex_Token_t token, void *buf, size_t nbytes, gex_AM_Arg_t addr_idx) {
void *source_addr = addr_tbl[(int)addr_idx];
gex_AM_ReplyMedium0(token, hidx_pong_medhandler, source_addr, 0, GEX_EVENT_NOW, 0);
}
void pong_medhandler(gex_Token_t token, void *buf, size_t nbytes) {
flag++;
}
void ping_longhandler(gex_Token_t token, void *buf, size_t nbytes, gex_AM_Arg_t addr_idx) {
void *source_addr = addr_tbl[(int)addr_idx];
if (buf != (addr_idx ? source_addr : prevseg)) {
ERR("Long Request handler received buf=%p when expecting %p", buf, source_addr);
}
gex_AM_ReplyLong1(token, hidx_pong_longhandler, source_addr, 0, source_addr, GEX_EVENT_NOW, 0, addr_idx);
}
void pong_longhandler(gex_Token_t token, void *buf, size_t nbytes, gex_AM_Arg_t addr_idx) {
void *source_addr = addr_tbl[(int)addr_idx];
if (buf != (addr_idx ? source_addr : nextseg)) {
ERR("Long Reply handler received buf=%p when expecting %p", buf, source_addr);
}
flag++;
}
/* ------------------------------------------------------------------------------------ */
static void testAMSrcAddr(void);
int main(int argc, char **argv) {
gex_AM_Entry_t htable[] = {
{ hidx_ping_medhandler, (gex_AM_Fn_t)ping_medhandler, GEX_FLAG_AM_REQUEST|GEX_FLAG_AM_MEDIUM, 1 },
{ hidx_pong_medhandler, (gex_AM_Fn_t)pong_medhandler, GEX_FLAG_AM_REPLY|GEX_FLAG_AM_MEDIUM, 0 },
{ hidx_ping_longhandler, (gex_AM_Fn_t)ping_longhandler, GEX_FLAG_AM_REQUEST|GEX_FLAG_AM_LONG, 1 },
{ hidx_pong_longhandler, (gex_AM_Fn_t)pong_longhandler, GEX_FLAG_AM_REPLY|GEX_FLAG_AM_LONG, 1 }
};
GASNET_Safe(gex_Client_Init(&myclient, &myep, &myteam, "testcore3", &argc, &argv, 0));
GASNET_Safe(gex_EP_RegisterHandlers(myep, htable, sizeof(htable)/sizeof(gex_AM_Entry_t)));
test_init("testcore3", 0, "[no argument]");
if (argc > 1) test_usage();
TEST_PRINT_CONDUITINFO();
mynode = gex_TM_QueryRank(myteam);
gex_Rank_t nnodes = gex_TM_QuerySize(myteam);
next = (mynode + 1) % nnodes;
prev = (mynode + nnodes - 1) % nnodes;
BARRIER();
// Test once prior to binding segments to the endpoints
// addr_tbl[0] == nextseg == prevseg trivially (all NULL)
testAMSrcAddr();
BARRIER();
GASNET_Safe(gex_Segment_Attach(&mysegment, myteam, TEST_SEGSZ_REQUEST));
// Test again with a bound segment and intialized addr_tbl[0], nextseg and prevseg
// (though they are all still NULL for GASNET_SEGMENT_EVERTHING)
addr_tbl[0] = myseg = TEST_MYSEG();
nextseg = TEST_SEG(next);
prevseg = TEST_SEG(prev);
BARRIER();
testAMSrcAddr();
MSG("done.");
gasnet_exit(test_errs ? 1 : 0);
return 0;
}
/* ------------------------------------------------------------------------------------ */
void testAMSrcAddr(void) {
GASNET_BEGIN_FUNCTION();
flag = 0;
// GASNet spec says we ignore source_addr when nbytes==0, for both Medium and Long.
// So, this test attempts various invalid source_address values.
// We pass the index, i, to allow the Reply to test all the values as well.
for (int i = 0; i < NUM_ADDRS; ++i) {
void *source_addr = addr_tbl[i];
int goal = flag + 1;
gex_AM_RequestMedium1(myteam, next, hidx_ping_medhandler, source_addr, 0, GEX_EVENT_NOW, 0, i);
GASNET_BLOCKUNTIL(flag == goal); ++goal;
// GASNet-EX requires initiator's "dest_addr" be passed to handler as "buf", even when nbytes==0
// So, we test that behavior in both the request and reply handlers.
gex_AM_RequestLong1(myteam, next, hidx_ping_longhandler, source_addr, 0, source_addr, GEX_EVENT_NOW, 0, i);
GASNET_BLOCKUNTIL(flag == goal); ++goal;
}
BARRIER();
}
|