photon  1.1
photon_buffertable.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 "photon_buffertable.h"
15 #include "libsync/locks.h"
16 #include "avl.h"
17 
18 static struct avl_table *btable = NULL;
19 static tatas_lock_t bt_lock;
20 
21 // returns 0 if a and b equal
22 // 1 if a > b
23 // -1 if a < b
24 static int bcmp(const void *a, const void *b, void *p) {
25  photonBI tst = &((photonBufferHandle)a)->bint;
26  photonBI res = &((photonBufferHandle)b)->bint;
27 
28  // below this region
29  if (tst->buf.addr < res->buf.addr) {
30  return -1;
31  }
32  // above this region
33  else if (tst->buf.addr > (res->buf.addr + res->buf.size)) {
34  return 1;
35  }
36  // fits in the region
37  else if ((tst->buf.addr + tst->buf.size) <= (res->buf.addr + res->buf.size)) {
38  return 0;
39  }
40  // overlap but doesn't fit
41  else {
42  return 1;
43  }
44 }
45 
46 int buffertable_init(int size) {
47  btable = avl_create(bcmp, NULL, NULL);
48  if (!btable) {
49  return PHOTON_ERROR;
50  }
51  sync_tatas_init(&bt_lock);
52  return PHOTON_OK;
53 }
54 
56  avl_destroy(btable, NULL);
57 }
58 
59 int buffertable_find_containing(void* addr, uint64_t size, photonBufferHandle* result) {
60  return buffertable_find_exact(addr, size, result);
61 }
62 
63 int buffertable_find_exact(void* addr, uint64_t size, photonBufferHandle* result) {
64  sync_tatas_acquire(&bt_lock);
65  {
67  tst.bint.buf.addr = (uintptr_t)addr;
68  tst.bint.buf.size = size;
69  void *res = avl_find(btable, &tst);
70  if (res) {
71  *result = (photonBufferHandle)res;
72  sync_tatas_release(&bt_lock);
73  return PHOTON_OK;
74  }
75  }
76  sync_tatas_release(&bt_lock);
77 
78  return PHOTON_ERROR;
79 }
80 
82  if (!btable) {
83  log_err("buffertable not initialized. Call buffertable_init() first.");
84  return PHOTON_ERROR;
85  }
86 
87  sync_tatas_acquire(&bt_lock);
88  {
89  void *res = avl_insert(btable, (void*)buf);
90  if (res) {
91  log_err("Tried to insert duplicate or overlapping buffer entry");
92  sync_tatas_release(&bt_lock);
93  return PHOTON_ERROR;
94  }
95  }
96  sync_tatas_release(&bt_lock);
97 
98  return PHOTON_OK;
99 }
100 
101 
103  if (!btable) {
104  log_err("buffertable not initialized. Call buffertable_init() first.");
105  return PHOTON_ERROR;
106  }
107 
108  sync_tatas_acquire(&bt_lock);
109  {
110  void *res = avl_delete(btable, (void*)buf);
111  if (!res) {
112  dbg_warn("Tried to delete buffer entry that doesn't exist");
113  sync_tatas_release(&bt_lock);
114  return PHOTON_ERROR;
115  }
116  }
117  sync_tatas_release(&bt_lock);
118 
119  return PHOTON_OK;
120 }
121 
int buffertable_remove(photonBufferHandle buf)
struct photon_buffer_handle_t * photonBufferHandle
int buffertable_find_exact(void *addr, uint64_t size, photonBufferHandle *result)
int buffertable_insert(photonBufferHandle buf)
#define PHOTON_ERROR
Error code, general error.
Definition: photon.h:32
struct photon_buffer_internal_t bint
#define PHOTON_OK
Photon success code.
Definition: photon.h:30
int buffertable_find_containing(void *addr, uint64_t size, photonBufferHandle *result)
int buffertable_init(int size)
void buffertable_finalize()
struct photon_buffer_internal_t * photonBI