5
/* initialization of data structures and setup of lapi internal parameters */
18
#include <sys/atomic_op.h>
22
#define ERROR(str,val) armci_die((str),(val))
23
#define BUF_TO_EVBUF(buf) ((lapi_cmpl_t*)(((char*)buf) - sizeof(lapi_cmpl_t)))
25
char err_msg_buf[LAPI_MAX_ERR_STRING]; /* for error msg returned by LAPI */
28
** macro to check return code of function calls. keeps return
29
** code checking logic from needing to be in main logic
31
#define CHECK(func_and_args) \
34
if ((rc = (func_and_args)) != LAPI_SUCCESS) { \
35
LAPI_Msg_string(rc, err_msg_buf); \
37
"LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc); \
38
armci_die("LAPI Error", 0); \
42
#if ARMCI_ENABLE_GPC_CALLS
43
extern gpc_buf_t *gpc_req;
45
int lapi_max_uhdr_data_sz; /* max data payload */
46
lapi_cmpl_t *cmpl_arr; /* completion state array, dim=NPROC */
47
lapi_cmpl_t hdr_cntr; /* AM header buffer counter */
48
lapi_cmpl_t buf_cntr; /* AM data buffer counter */
49
lapi_cmpl_t* ack_cntr; /* ACK counter used in handshaking protocols
50
between origin and target */
51
lapi_cmpl_t* get_cntr; /* counter used with lapi_get */
52
lapi_user_cxt_t *lapi_remote_cxt; /* Remote context for RDMA call */
55
lapi_info_t lapi_info;
57
lapi_handle_t lapi_handle;
59
pthread_mutex_t _armci_mutex_thread=PTHREAD_MUTEX_INITIALIZER;
62
double _armci_rcv_buf[MSG_BUFLEN_DBL];
63
char* MessageRcvBuffer = (char*)_armci_rcv_buf;
64
char* MessageSndBuffer = (char*)0;
66
extern void armci_waitsome(int factor);
68
/************* LAPI Active Message handlers *******************************/
70
volatile static int hndlcnt=0, header_cnt=0;
72
static long num_malloc=0; /* trace and limit the number malloc calls in HH */
73
#define MAX_NUM_MALLOC 100
75
/* trace state of accumulate lock */
76
int kevin_ok=1; /* "1" indicates that no other thread is holding the lock */
79
void armci_completion_handler(lapi_handle_t *t_hndl, void *save)
81
lapi_handle_t hndl = *t_hndl;
85
request_header_t *msginfo = (request_header_t *)save;
86
char *descr= (char*)(msginfo+1), *buf=MessageRcvBuffer;
87
int buflen=MSG_BUFLEN;
88
#if ARMCI_ENABLE_GPC_CALLS
89
extern pthread_t data_server;
90
data_server = pthread_self();
94
fprintf(stderr,"%d:CH:op=%d from=%d datalen=%d dscrlen=%d\n", armci_me,
95
msginfo->operation, msginfo->from,msginfo->datalen,msginfo->dscrlen);
97
/*** assure that descriptor and data are in the right format and place ***/
98
if( msginfo->dscrlen < 0 || msginfo->datalen <0 ){
99
/* for large put/acc/scatter need to get the data */
101
lapi_cntr_t req_cntr;
103
char *origin_ptr = msginfo->tag.buf;
105
if (msginfo->dscrlen<0) {
106
descr =MessageRcvBuffer;
107
msginfo->dscrlen = -msginfo->dscrlen;
108
buf = descr + msginfo->dscrlen;
109
buflen += msginfo->dscrlen;
110
bytes += msginfo->dscrlen;
113
if (msginfo->datalen <0){
114
msginfo->datalen = -msginfo->datalen;
115
bytes += msginfo->datalen;
118
if(rc=LAPI_Setcntr(hndl, &req_cntr, 0)) ERROR("CH:setcntr failed",rc);
119
if(rc=LAPI_Get(hndl, (uint)msginfo->from, bytes,
120
origin_ptr, MessageRcvBuffer,
121
msginfo->tag.cntr,&req_cntr))ERROR("CH:LAPI_Get failed",rc);
123
if(rc=LAPI_Waitcntr(hndl, &req_cntr,1,NULL))ERROR("CH:Waitcntr failed",rc);
128
/* desc is in save, data could be but not for GET */
129
if(msginfo->operation !=GET)buf = descr + msginfo->dscrlen;
133
/* fprintf(stderr,"CH: val=%lf\n",*(double*)(buf+msginfo->datalen -8));*/
136
/*** dispatch request to the appropriate handler function ***/
137
switch(msginfo->operation){
138
case LOCK: armci_server_lock(msginfo);
140
case UNLOCK: armci_server_unlock(msginfo, descr);
143
if(msginfo->format == STRIDED)
144
armci_server(msginfo, descr, buf, buflen);
146
armci_server_vector(msginfo, descr, buf, buflen);
151
(void)fetch_and_add(&num_malloc, (long)-1);
153
(void)fetch_and_addlp(&num_malloc, (long)-1);
160
void* armci_header_handler(lapi_handle_t *t_hndl, void *uhdr, uint *t_uhdrlen,
161
uint *msglen, compl_hndlr_t **handler, void** psave)
163
lapi_handle_t hndl = *t_hndl;
164
uint uhdrlen = *t_uhdrlen;
165
request_header_t *msginfo = (request_header_t *)uhdr;
168
fprintf(stderr,"%d:HH: op=%d from %d\n",armci_me,msginfo->operation,
170
if(msginfo->to != armci_me)
171
armci_die("wrong message delivered",msginfo->to);
173
/* process small requests that do not require comms in header handler */
174
if(msginfo->datalen >0 && msginfo->dscrlen>0 && msginfo->operation != GET
175
&& msginfo->operation != LOCK && msginfo->operation != UNLOCK){
177
/* If another thread is in accumulate use compl. handler path:
178
* Try to avoid blocking inside HH which degrades Lapi performance.
179
* The completion handler path requires malloc to save request info.
180
* Only up to approx. MAX_NUM_MALLOC requests can be rescheduled to
181
* run in CH instead of HH.
182
* MAX_NUM_MALLOC is a soft limit to avoid cost of locking when reading
185
if( msginfo->operation==PUT || num_malloc>MAX_NUM_MALLOC || kevin_ok){
187
char *descr = (char*)(msginfo+1);
188
char *buf = descr + msginfo->dscrlen;
189
int buflen = uhdrlen - sizeof(request_header_t) - msginfo->dscrlen;
192
fprintf(stderr,"%d:HH: buf =%lf\n",armci_me,*(double*)buf);
193
if(msginfo->format == STRIDED)
194
armci_server(msginfo, descr, buf, buflen);
196
armci_server_vector(msginfo, descr, buf, buflen);
198
/* fprintf(stderr,"%d:HH: getting out of server\n",armci_me);*/
206
(void)fetch_and_add(&num_malloc, (long)1);
208
(void)fetch_and_addlp(&num_malloc, (long)1); /* AIX atomic increment */
211
msginfo = (request_header_t*) malloc(uhdrlen); /* recycle pointer */
212
if(!msginfo) ERROR("HH: malloc failed in header handler",num_malloc);
214
/* save the request info for processing in compl. handler */
215
memcpy((char*)msginfo, uhdr, uhdrlen);
217
*handler = armci_completion_handler;
223
void armci_send_req(int proc, request_header_t* msginfo, int len)
225
int msglen = sizeof(request_header_t);
226
lapi_cntr_t *pcmpl_cntr, *pcntr = &(BUF_TO_EVBUF(msginfo)->cntr);
229
msginfo->tag.cntr= pcntr;
230
#if ARMCI_ENABLE_GPC_CALLS
231
if(msginfo->operation==GET && msginfo->format==VECTOR && msginfo->ehlen){
232
msginfo->tag.buf = (char *)(msginfo+1)+msginfo->dscrlen;
236
msginfo->tag.buf = msginfo+1;
238
if(msginfo->operation==GET || msginfo->operation==LOCK){
240
SET_COUNTER(*(lapi_cmpl_t*)pcntr,1);/*dataarrive in same buf*/
241
/*The GPC case. Note that we don't use the parameter len*/
242
if(msginfo->format==VECTOR && msginfo->ehlen > 0)
243
msglen += msginfo->datalen;
244
if(lapi_max_uhdr_data_sz < msginfo->dscrlen){
246
msginfo->dscrlen = -msginfo->dscrlen; /* no room for descriptor */
247
pcntr = NULL; /* GET(descr) from CH will increment buf cntr */
249
}else msglen += msginfo->dscrlen;
252
we should send the mutex, too. When op==LOCK, Value of len parameter
253
is already sizeof(reqest_header_t)+sizeof(int), since we dont use
254
len but construct our own msglen, we need to add sizeof(int).
256
if(msginfo->operation==LOCK) msglen += sizeof(int);
258
pcmpl_cntr=NULL; /* don't trace completion status for load ops */
260
}else if (msginfo->operation==UNLOCK){
262
msglen += msginfo->dscrlen;
263
pcmpl_cntr=NULL; /* don't trace completion status for unlock */
267
if(lapi_max_uhdr_data_sz < (msginfo->datalen + msginfo->dscrlen)){
269
msginfo->datalen = -msginfo->datalen;
270
msginfo->dscrlen = -msginfo->dscrlen;
271
pcntr = NULL; /* GET/LOCK from CH will increment buf cntr */
273
}else msglen += msginfo->dscrlen+msginfo->datalen;
275
/* trace completion of store ops */
276
pcmpl_cntr = &cmpl_arr[msginfo->to].cntr;
280
if(msginfo->operation==PUT || ARMCI_ACC(msginfo->operation))
281
UPDATE_FENCE_STATE(msginfo->to, msginfo->operation, 1);
283
if((rc=LAPI_Amsend(lapi_handle,(uint)msginfo->to,
284
(void*)armci_header_handler, msginfo, msglen, NULL, 0,
285
NULL, pcntr, pcmpl_cntr))) armci_die("AM failed",rc);
287
if(DEBUG_) fprintf(stderr,"%d sending req=%d to %d\n",
288
armci_me, msginfo->operation, proc);
293
/*\ client sends strided data + request to server
295
void armci_send_strided(int proc, request_header_t *msginfo, char *bdata,
296
void *ptr, int strides, int stride_arr[], int count[])
299
armci_write_strided(ptr, strides, stride_arr, count, bdata);
300
armci_send_req(proc,msginfo,msginfo->bytes + sizeof(request_header_t));
304
/*\ server sends data back to client
306
void armci_send_data(request_header_t* msginfo, void *data)
308
armci_lapi_send(msginfo->tag, data, msginfo->datalen, msginfo->from);
312
/*\ server sends strided data back to client
314
void armci_send_strided_data(int proc, request_header_t *msginfo, char *bdata,
315
void *ptr, int strides, int stride_arr[], int count[])
317
armci_write_strided(ptr, strides, stride_arr, count, bdata);
318
armci_lapi_send(msginfo->tag, bdata, msginfo->datalen, msginfo->from);
322
char* armci_rcv_data(int proc, request_header_t *msginfo)
324
lapi_cmpl_t *pcntr=BUF_TO_EVBUF(msginfo);
325
CLEAR_COUNTER((*pcntr));
326
#if ARMCI_ENABLE_GPC_CALLS
327
if(msginfo->operation==GET && msginfo->format==VECTOR && msginfo->ehlen){
328
return((char *)(msginfo+1)+msginfo->dscrlen);
332
return (char*)(msginfo+1);
337
/*\ client receives strided data from server
339
void armci_rcv_strided_data(int proc, request_header_t* msginfo, int datalen,
340
void *ptr, int strides, int stride_arr[], int count[])
342
lapi_cmpl_t *pcntr=BUF_TO_EVBUF(msginfo);
343
CLEAR_COUNTER((*pcntr));
344
armci_read_strided(ptr, strides, stride_arr, count, (char*)(msginfo+1));
349
/*\ client receives vector data from server to buffer and unpacks it
351
void armci_rcv_vector_data(int proc, request_header_t* msginfo,
352
armci_giov_t darr[], int len)
355
buf = armci_rcv_data(proc,msginfo);
356
armci_vector_from_buf(darr, len, buf);
360
/*\ initialization of LAPI related data structures
362
void armci_init_lapi()
365
int lapi_max_uhdr_sz;
367
lapi_remote_cxt_t util_cxt; /* For call to obtain rCxt */
370
rc = LAPI_Init(&lapi_handle, &lapi_info);
371
if(rc) ERROR("lapi_init failed",rc);
374
/* set the max limit for AM header data length */
375
rc = LAPI_Qenv(lapi_handle,MAX_UHDR_SZ, &lapi_max_uhdr_sz);
376
if(rc) ERROR("armci_init_lapi: LAPI_Qenv failed", rc);
378
/* fprintf(stderr,"max header size = %d\n",lapi_max_uhdr_sz);*/
380
/* how much data can fit into AM header ? */
381
lapi_max_uhdr_data_sz = lapi_max_uhdr_sz - sizeof(request_header_t);
383
/* allocate memory for completion state array */
384
cmpl_arr = (lapi_cmpl_t*)malloc(armci_nproc*sizeof(lapi_cmpl_t));
385
if(cmpl_arr==NULL) ERROR("armci_init_lapi:malloc for cmpl_arr failed",0);
387
/* allocate memory for ack and get counters, 1 if not thread safe */
389
ack_cntr = calloc(armci_user_threads.max, sizeof(lapi_cmpl_t));
390
get_cntr = calloc(armci_user_threads.max, sizeof(lapi_cmpl_t));
392
ack_cntr = calloc(1, sizeof(lapi_cmpl_t));
393
get_cntr = calloc(1, sizeof(lapi_cmpl_t));
395
if (!(ack_cntr && get_cntr))
396
ERROR("armci_init_lapi:calloc for ack or get counters failed",0);
398
/* initialize completion state array */
399
for(p = 0; p< armci_nproc; p++){
400
rc = LAPI_Setcntr(lapi_handle, &cmpl_arr[p].cntr, 0);
401
if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (arr)",rc);
402
cmpl_arr[p].oper = -1;
406
/* initialize ack/buf/hdr counters */
408
# define N armci_user_threads.max
412
for (p = 0; p < N; p++) {
413
rc = LAPI_Setcntr(lapi_handle, &(ack_cntr[p].cntr), 0);
414
if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (ack)",rc);
417
rc = LAPI_Setcntr(lapi_handle, &(get_cntr[p].cntr), 0);
418
if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (get)",rc);
421
rc = LAPI_Setcntr(lapi_handle, &hdr_cntr.cntr, 0);
422
if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (hdr)",rc);
424
rc = LAPI_Setcntr(lapi_handle, &buf_cntr.cntr, 0);
425
if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (buf)",rc);
428
pcntr = (lapi_cmpl_t*)MessageSndBuffer;
429
rc = LAPI_Setcntr(lapi_handle, &pcntr->cntr, 0);
430
if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (bufcntr)",rc);
436
lapi_remote_cxt = (lapi_user_cxt_t*)malloc(armci_nproc *
437
sizeof(lapi_user_cxt_t));
438
if(lapi_remote_cxt==NULL) ERROR("armci_init_lapi: rCxt malloc failed",0);
440
/* obtain remote context "rCxt" for RDMA Operation of all procs */
441
for(p = 0; p< armci_nproc; p++){
442
if(p==armci_me) continue;
443
util_cxt.Util_type = LAPI_REMOTE_RCXT;
444
util_cxt.operation = LAPI_RDMA_ACQUIRE;
446
CHECK(LAPI_Util(lapi_handle, (lapi_util_t *) &util_cxt));
447
lapi_remote_cxt[p] = util_cxt.usr_rcxt;
453
/* for high performance, disable LAPI internal error checking */
454
LAPI_Senv(lapi_handle, ERROR_CHK, 0);
458
/* make sure that interrupt mode is on */
459
LAPI_Senv(lapi_handle, INTERRUPT_SET, 1);
461
/* initialize buffer managment module */
465
CHECK((LAPI_Gfence(lapi_handle)));
467
#if ARMCI_ENABLE_GPC_CALLS
468
gpc_req = (gpc_buf_t *)malloc(sizeof(gpc_buf_t)*MAX_GPC_REQ);
469
if(gpc_req==NULL)armci_die("malloc for gpc failed",sizeof(gpc_buf_t));
475
void armci_term_lapi()
478
lapi_remote_cxt_t util_cxt; /* For call to obtain rCxt */
481
CHECK((LAPI_Gfence(lapi_handle)));
483
/* release remote context "rCxt" for RDMA Operation of all procs */
484
for(p = 0; p< armci_nproc; p++){
485
if(p==armci_me) continue;
486
util_cxt.Util_type = LAPI_REMOTE_RCXT;
487
util_cxt.operation = LAPI_RDMA_RELEASE;
489
util_cxt.usr_rcxt = lapi_remote_cxt[p];
490
CHECK(LAPI_Util(lapi_handle, (lapi_util_t *) &util_cxt));
492
free(lapi_remote_cxt);
496
CHECK((LAPI_Term(lapi_handle))); /* terminate the LAPI handle */
503
/* primitive pseudo message-passing on top of lapi */
505
/* send data to remote process using p specified message tag */
506
/* tag contains address of receive buffer guarded by cntr at process p */
507
void armci_lapi_send(msg_tag_t tag, void* data, int len, int p)
510
lapi_cntr_t org_cntr;
512
lapi_cntr_t *cntr = tag.cntr;
513
if(!buf)ERROR("armci_lapi_send: NULL tag(buf) error",0);
514
if(!cntr)ERROR("armci_lapi_send: NULL tag(cntr) error",0);
516
rc=LAPI_Setcntr(lapi_handle, &org_cntr, 0);
517
if(rc) ERROR("armci_lapi_send:setcntr failed",rc);
518
rc=LAPI_Put(lapi_handle, (uint)p, (uint)len, buf, data,
519
cntr, &org_cntr, NULL);
520
if(rc) ERROR("armci_lapi_send:put failed",rc);
521
rc+=LAPI_Waitcntr(lapi_handle, &org_cntr, 1, NULL);
522
if(rc) ERROR("armci_lapi_send:waitcntr failed",rc);
525
/* subroutine versions of macros disabling and enabling interrupts */
537
void print_counters_()
540
printf("bufcntr: val =%d cntr=%d\n", buf_cntr.val, buf_cntr.cntr);
541
for(i=0; i< armci_nproc;i++){
542
printf("cmpl_arr: val=%d cntr=%d oper=%d\n",cmpl_arr[i].val,
543
cmpl_arr[i].cntr, cmpl_arr[i].oper);
550
void armci_client_direct_send(int p, void *src_buf, void *dst_buf,
551
int len, void** contextptr, int nbtag,
552
ARMCI_MEMHDL_T *lochdl,ARMCI_MEMHDL_T *remhdl) {
554
lapi_xfer_t xfer_struct; /* Data structure for the xfer call */
555
lapi_rdma_tag_t lapi_rdma_tag; /* RDMA notification tag */
556
uint src_offset, tgt_offset;
559
/* can be any number that fits in ushort */
562
/* CHECK: offset problem. what if client and server attached (shmat) at
564
src_offset = (char *)src_buf- (char *)lochdl->start;
565
tgt_offset = (char *)dst_buf - (char *)remhdl->start;
568
printf("%d: Doing LAPI_Xfer (RDMA Put): dst=%d srchdl_start=%p remhdl_start=%p (bytes=%ld src_off=%d tgt_off=%d)\n", armci_me, p, lochdl->start, remhdl->start, len, src_offset, tgt_offset); fflush(stdout);
571
bzero(&xfer_struct, sizeof(xfer_struct));
572
xfer_struct.HwXfer.Xfer_type = LAPI_RDMA_XFER;
573
xfer_struct.HwXfer.tgt = p;
574
/*xfer_struct.HwXfer.op = LAPI_RDMA_PUT|LAPI_RCNTR_UPDATE;*/
575
xfer_struct.HwXfer.op = LAPI_RDMA_PUT;
576
xfer_struct.HwXfer.rdma_tag = lapi_rdma_tag;
577
xfer_struct.HwXfer.remote_cxt = lapi_remote_cxt[p];
578
xfer_struct.HwXfer.src_pvo = lochdl->pvo;
579
xfer_struct.HwXfer.tgt_pvo = remhdl->pvo;
580
xfer_struct.HwXfer.src_offset = src_offset;
581
xfer_struct.HwXfer.tgt_offset = tgt_offset;
582
xfer_struct.HwXfer.len = (ulong) (len);
583
xfer_struct.HwXfer.shdlr = (scompl_hndlr_t *) NULL;
584
xfer_struct.HwXfer.sinfo = (void *) NULL;
585
xfer_struct.HwXfer.org_cntr = &(ack_cntr->cntr);
587
/* Initiate RDMA Xfer */
588
if((rc = LAPI_Xfer(lapi_handle, &xfer_struct)) != LAPI_SUCCESS) {
589
LAPI_Msg_string(rc, err_msg_buf);
590
fprintf(stderr, "LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc);
591
armci_die("LAPI_Xfer (RDMA Put) failed", 0);
594
/* wait for RDMA completion */
595
rc = LAPI_Waitcntr(lapi_handle, &(ack_cntr->cntr),1,&val);
596
if(rc != LAPI_SUCCESS) {
597
LAPI_Msg_string(rc, err_msg_buf);
598
fprintf(stderr, "LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc);
599
armci_die("LAPI_Waitcntr (RDMA Put) failed", 0);
602
/* CHECK((LAPI_Fence(lapi_handle))); */
605
printf("%d: Completed LAPI_Xfer RDMA (Put): dst=%d\n", armci_me, p);
610
void armci_client_direct_get(int p, void *src_buf, void *dst_buf,
611
int len, void** cptr, int nbtag,
612
ARMCI_MEMHDL_T *lochdl, ARMCI_MEMHDL_T *remhdl) {
614
lapi_xfer_t xfer_struct; /* Data structure for the xfer call */
615
lapi_rdma_tag_t lapi_rdma_tag; /* RDMA notification tag */
616
uint src_offset, tgt_offset;
619
/* can be any number that fits in ushort */
622
/* CHECK: offset problem. what if client and server attached (shmat) at
624
src_offset = (char *)dst_buf- (char *)lochdl->start;
625
tgt_offset = (char *)src_buf - (char *)remhdl->start;
628
printf("%d: Doing LAPI_Xfer (RDMA Get): dst=%d srchdl_start=%p remhdl_start=%p (bytes=%ld src_off=%d tgt_off=%d)\n", armci_me, p, lochdl->start, remhdl->start, len, src_offset, tgt_offset); fflush(stdout);
630
bzero(&xfer_struct, sizeof(xfer_struct));
631
xfer_struct.HwXfer.Xfer_type = LAPI_RDMA_XFER;
632
xfer_struct.HwXfer.tgt = p;
633
/*xfer_struct.HwXfer.op = LAPI_RDMA_GET|LAPI_RCNTR_UPDATE;*/
634
xfer_struct.HwXfer.op = LAPI_RDMA_GET;
635
xfer_struct.HwXfer.rdma_tag = lapi_rdma_tag;
636
xfer_struct.HwXfer.remote_cxt = lapi_remote_cxt[p];
637
xfer_struct.HwXfer.src_pvo = lochdl->pvo;
638
xfer_struct.HwXfer.tgt_pvo = remhdl->pvo;
639
xfer_struct.HwXfer.src_offset = src_offset;
640
xfer_struct.HwXfer.tgt_offset = tgt_offset;
641
xfer_struct.HwXfer.len = (ulong) (len);
642
xfer_struct.HwXfer.shdlr = (scompl_hndlr_t *) NULL;
643
xfer_struct.HwXfer.sinfo = (void *) NULL;
644
xfer_struct.HwXfer.org_cntr = &(get_cntr->cntr);
646
/* Initiate RDMA Xfer */
647
if((rc = LAPI_Xfer(lapi_handle, &xfer_struct)) != LAPI_SUCCESS) {
648
LAPI_Msg_string(rc, err_msg_buf);
649
fprintf(stderr, "LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc);
650
armci_die("LAPI_Xfer (RDMA Get) failed", 0);
653
/* wait for RDMA completion */
654
rc = LAPI_Waitcntr(lapi_handle, &(get_cntr->cntr),1,&val);
655
if(rc != LAPI_SUCCESS) {
656
LAPI_Msg_string(rc, err_msg_buf);
657
fprintf(stderr, "LAPI ERROR: %s, rc = %d\n", err_msg_buf, rc);
658
armci_die("LAPI_Waitcntr (RDMA Get) failed", 0);
662
printf("%d: Completed LAPI_Xfer (RDMA Get): dst=%d\n", armci_me, p);
667
int armci_pin_contig_hndl(void *ptr, int bytes, ARMCI_MEMHDL_T *memhdl)
670
lapi_get_pvo_t util_pvo; /* For call to obtain PVO */
673
/* translate and pin the buffer to the adapter */
674
util_pvo.Util_type = LAPI_XLATE_ADDRESS;
675
util_pvo.length = bytes;
676
util_pvo.usr_pvo = 0;
677
util_pvo.address = ptr;
678
util_pvo.operation = LAPI_RDMA_ACQUIRE;
679
/*bzero(ptr, bytes);*/ /* CHECK: Is touching the entire shmem sgement feasible */
680
if((rc=LAPI_Util(lapi_handle, (lapi_util_t *) &util_pvo)) != LAPI_SUCCESS) {
684
memhdl->pvo = util_pvo.usr_pvo;
688
printf("\n%d:armci_pin_contig_hndl(): memhdl(pvo)=%ld ptr=%p bytes=%ld\n",
689
armci_me, (long)memhdl->pvo, ptr, bytes);fflush(stdout);
695
void armci_network_client_deregister_memory(ARMCI_MEMHDL_T *mh)
697
fprintf(stderr," armci_network_client_deregister_memory not available\n");
702
void armci_network_server_deregister_memory(ARMCI_MEMHDL_T *mh)
704
fprintf(stderr," armci_network_client_deregister_memory not available\n");
707
#endif /* LAPI_RDMA */
712
void armci_lapi_lock(int *lock)
714
atomic_p word_addr = (atomic_p)lock;
720
if(_check_lock(word_addr, 0, LOCKED) == FALSE )
721
break; /* we got the lock */
728
/* yield processor to another thread */
729
/* cannot yield w/o affecting thread priority - better sleep */
732
/* call usleep to notify scheduler */
739
void armci_lapi_unlock(int *lock)
741
atomic_p word_addr = (atomic_p)lock;
743
if(_check_lock(word_addr, LOCKED, 0) == TRUE )
744
armci_die("somebody else unlocked",0);