photon  1.1
photon_rdma_INFO_ledger.c
Go to the documentation of this file.
1 // =============================================================================
2 // Photon RDMA Library (libphoton)
3 //
4 // Copyright (c) 2016, Trustees of Indiana University,
5 // All rights reserved.
6 //
7 // This software may be modified and distributed under the terms of the BSD
8 // license. See the COPYING file for details.
9 //
10 // This software was created at the Indiana University Center for Research in
11 // Extreme Scale Technologies (CREST).
12 // =============================================================================
13 
14 #include <stdlib.h>
15 #include <string.h>
16 #include <stddef.h>
17 
19 #include "photon_exchange.h"
20 #include "photon_event.h"
21 #include "logging.h"
22 
23 static int _get_remote_progress(int proc, photonRILedger buf);
24 
25 photonRILedger photon_ri_ledger_create_reuse(photonRILedgerEntry ledger_buffer, int ledger_size, int prefix) {
26  photonRILedger new;
27 
28  new = (struct photon_ri_ledger_t *)((uintptr_t)ledger_buffer + PHOTON_INFO_SSIZE(ledger_size) -
29  sizeof(struct photon_ri_ledger_t));
30 
31  memset(new, 0, sizeof(struct photon_ri_ledger_t));
32 
33  new->entries = ledger_buffer;
34 
35  // we bzero this out so that valgrind doesn't believe these are
36  // "uninitialized". They get filled in via RDMA so valgrind doesn't
37  // know that the values have been filled in
38  memset(new->entries, 0, sizeof(struct photon_ri_ledger_entry_t) * ledger_size);
39 
40  new->prog = 0;
41  new->curr = 0;
42  new->num_entries = ledger_size;
43  new->acct.rcur = 0;
44  new->acct.rloc = 0;
45  new->acct.event_prefix = prefix;
46 
47  return new;
48 }
49 
51  //free(ledger);
52 }
53 
55  uint64_t curr, tail, rcur;
56  photonBackend be = photon_processes[proc].backend;
57 
58  int rc = be->tx_size_left(proc);
59  if (rc < 2) {
60  return -1;
61  }
62 
63  do {
64  rcur = sync_load(&l->acct.rcur, SYNC_RELAXED);
65  curr = sync_load(&l->curr, SYNC_RELAXED);
66  tail = sync_load(&l->tail, SYNC_RELAXED);
67  if ((curr - tail) >= l->num_entries) {
68  log_err("Exceeded number of outstanding RI ledger entries - increase ledger size or wait for completion");
69  return -1;
70  }
71  if ((curr - rcur) >= l->num_entries) {
72  // receiver not ready, request an updated rcur
73  _get_remote_progress(proc, l);
74  dbg_trace("No new info ledger entry until receiver catches up...");
75  return -2;
76  }
77  } while (!sync_cas(&l->curr, &curr, curr+1, SYNC_RELAXED, SYNC_RELAXED));
78 
79  if ((curr - rcur) == (int)(l->num_entries * 0.8)) {
80  // do a pro-active fetch of the remote ledger progress
81  _get_remote_progress(proc, l);
82  }
83 
84  return curr & (l->num_entries - 1);
85 }
86 
87 static int _get_remote_progress(int proc, photonRILedger buf) {
88  int rc;
89  uint32_t rloc;
90  uint64_t cookie;
91  uintptr_t rmt_addr;
92  photonRequest req;
93  photonBackend be = photon_processes[proc].backend;
94 
95  rc = __photon_try_one_event(&req);
96  if (rc == PHOTON_EVENT_ERROR) {
97  dbg_err("Failure getting event");
98  return PHOTON_ERROR;
99  }
100 
101  rloc = 0;
102  if (sync_cas(&buf->acct.rloc, &rloc, 1, SYNC_ACQUIRE, SYNC_RELAXED)) {
103 
104  dbg_trace("Fetching remote info ledger (%d) curr at rcur: %llu", proc, buf->acct.rcur);
105 
106  rmt_addr = buf->remote.addr + PHOTON_INFO_SSIZE(buf->num_entries) -
107  sizeof(struct photon_ri_ledger_t) + offsetof(struct photon_ri_ledger_t, prog);
108 
109  cookie = ( (uint64_t)buf->acct.event_prefix<<32) | proc;
110 
111  rc = be->rdma_get(proc, (uintptr_t)&buf->acct.rcur, rmt_addr, sizeof(buf->acct.rcur),
112  &(shared_storage->bint.buf), &buf->remote, cookie, 0);
113  if (rc != PHOTON_OK) {
114  dbg_err("RDMA GET for remote info ledger progress counter failed");
115  return PHOTON_ERROR;
116  }
117  }
118 
119  return PHOTON_OK;
120 }
photonRILedger photon_ri_ledger_create_reuse(photonRILedgerEntry ledger_buffer, int ledger_size, int prefix)
struct photon_ri_ledger_entry_t * photonRILedgerEntry
photonBufferHandle shared_storage
struct photon_ri_ledger_t * photonRILedger
#define PHOTON_INFO_SSIZE(c)
photonBackend backend
struct photon_req_t * photonRequest
ProcessInfo * photon_processes
void photon_ri_ledger_free(photonRILedger ledger)
#define PHOTON_ERROR
Error code, general error.
Definition: photon.h:32
int photon_ri_ledger_get_next(int proc, photonRILedger l)
#define PHOTON_OK
Photon success code.
Definition: photon.h:30
#define PHOTON_EVENT_ERROR
Definition: photon_event.h:24
int __photon_try_one_event(photonRequest *rreq)
Definition: photon_event.c:387