summaryrefslogtreecommitdiff
path: root/src/lib/shm_du_map.c
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-05-07 16:11:09 +0200
committerdimitri staessens <[email protected]>2016-05-07 16:11:09 +0200
commiteb9f44379d5316e7f7e9311d7a66d2041eca743a (patch)
tree2489605a42bb2c9582c0c4e912c2de0c40512b2a /src/lib/shm_du_map.c
parentde8f2015cbd015b1cced366cb12c054be62c23b1 (diff)
downloadouroboros-eb9f44379d5316e7f7e9311d7a66d2041eca743a.tar.gz
ouroboros-eb9f44379d5316e7f7e9311d7a66d2041eca743a.zip
irmd: flow allocation and fast path
This commit has a first implementation of flow allocation (the "slow path") and read/write (the "fast path") for ouroboros. It provides basic but unstable communications over the shared memory. It required a lot of changes all over the stack, and fixes a number of previously undetected issues. This PR still need heavy revision regarding data model, locking and cleanup. lib/dev: modifications to the API. It now uses an ap_init() call to set the AP name and sets the Instance ID to the pid of the process. It also binds the AP to the shared memory and creates tables for mappings in the fast path. A call to ap_fini() releases the resources. lib/shm_ap_rbuff: added ring buffer for data exchange between processes in the fast path. It passes an index in the shm_du_map. lib/shm_du_map: rewrote API to work with calls from dev.c. Garbage collector added. Tests updated to new API. ipcpd/ipcp-data: removed everything related to flows, as these are universal for all ap's and kept in ap_data (dev.c), or similar structs for shim ipcps. shim-udp: added flow allocator and read/write functions and shm elements. irmd: revised data model and structures necessary for flow allocation. tools: echo updated to new dev.h API. messaging system was updated to comply with new flow allocation messages. All exchanges use pid and port_id to bootstrap the fast path.
Diffstat (limited to 'src/lib/shm_du_map.c')
-rw-r--r--src/lib/shm_du_map.c143
1 files changed, 104 insertions, 39 deletions
diff --git a/src/lib/shm_du_map.c b/src/lib/shm_du_map.c
index dfccca6a..56062c9d 100644
--- a/src/lib/shm_du_map.c
+++ b/src/lib/shm_du_map.c
@@ -45,6 +45,9 @@
((struct shm_du_buff *)(dum->shm_base + (*dum->ptr_tail * \
SHM_DU_BUFF_BLOCK_SIZE)))
+#define idx_to_du_buff_ptr(dum, idx) \
+ ((struct shm_du_buff *)(dum->shm_base + (idx * SHM_DU_BUFF_BLOCK_SIZE)))
+
#define block_ptr_to_idx(dum, sdb) \
(((uint8_t *)sdb - dum->shm_base) / SHM_DU_BUFF_BLOCK_SIZE)
@@ -52,27 +55,31 @@
& (SHM_BLOCKS_IN_MAP - 1))
#define shm_map_free(dum, i)(shm_map_used(dum) + i < SHM_BLOCKS_IN_MAP)
+#define sdu_size(dum, idx) (idx_to_du_buff_ptr(dum, idx)->du_tail - \
+ idx_to_du_buff_ptr(dum, idx)->du_head)
+
#define MIN(a,b)(a < b ? a : b)
struct shm_du_buff {
- size_t size;
- size_t du_head;
- size_t du_tail;
+ size_t size;
+ size_t du_head;
+ size_t du_tail;
+ size_t garbage;
};
struct shm_du_map {
- uint8_t * shm_base; /* start of blocks */
- size_t * ptr_head; /* start of ringbuffer head */
- size_t * ptr_tail; /* start of ringbuffer tail */
- pthread_mutex_t * shm_mutex; /* lock all free space in shm */
- int fd;
+ uint8_t * shm_base; /* start of blocks */
+ size_t * ptr_head; /* start of ringbuffer head */
+ size_t * ptr_tail; /* start of ringbuffer tail */
+ pthread_mutex_t * shm_mutex; /* lock all free space in shm */
+ int fd;
};
struct shm_du_map * shm_du_map_create()
{
struct shm_du_map * dum;
int shm_fd;
- uint8_t * shm_base;
+ uint8_t * shm_base;
pthread_mutexattr_t attr;
dum = malloc(sizeof *dum);
@@ -141,7 +148,13 @@ struct shm_du_map * shm_du_map_open()
{
struct shm_du_map * dum;
int shm_fd;
- uint8_t * shm_base;
+ uint8_t * shm_base;
+
+ dum = malloc(sizeof *dum);
+ if (dum == NULL) {
+ LOG_DBGF("Could not allocate struct.");
+ return NULL;
+ }
shm_fd = shm_open(SHM_DU_MAP_FILENAME, O_RDWR, 0666);
if (shm_fd == -1) {
@@ -166,12 +179,6 @@ struct shm_du_map * shm_du_map_open()
return NULL;
}
- dum = malloc(sizeof *dum);
- if (dum == NULL) {
- LOG_DBGF("Could not allocate struct.");
- return NULL;
- }
-
dum->shm_base = shm_base;
dum->ptr_head = (size_t *)
((uint8_t *) dum->shm_base + SHM_BLOCKS_SIZE);
@@ -195,38 +202,52 @@ void shm_du_map_close(struct shm_du_map * dum)
if (munmap(dum->shm_base, SHM_FILE_SIZE) == -1)
LOG_DBGF("Couldn't unmap shared memory.");
+ free(dum);
+}
+
+void shm_du_map_destroy(struct shm_du_map * dum)
+{
+ if (dum == NULL) {
+ LOG_DBGF("Bogus input. Bugging out.");
+ return;
+ }
+
+ if (munmap(dum->shm_base, SHM_FILE_SIZE) == -1)
+ LOG_DBGF("Couldn't unmap shared memory.");
+
if (shm_unlink(SHM_DU_MAP_FILENAME) == -1)
LOG_DBGF("Failed to unlink shm.");
free(dum);
}
-struct shm_du_buff * shm_create_du_buff(struct shm_du_map * dum,
- size_t size,
- size_t headspace,
- uint8_t * data,
- size_t len)
+int shm_create_du_buff(struct shm_du_map * dum,
+ size_t size,
+ size_t headspace,
+ uint8_t * data,
+ size_t len)
{
struct shm_du_buff * sdb;
long blocks = 0;
int sz = size + sizeof *sdb;
int sz2 = headspace + len + sizeof *sdb;
- uint8_t * write_pos;
+ uint8_t * write_pos;
size_t copy_len;
+ size_t index;
if (dum == NULL || data == NULL) {
LOG_DBGF("Bogus input, bugging out.");
- return NULL;
+ return -1;
}
if (headspace >= size) {
LOG_DBGF("Index out of bounds.");
- return NULL;
+ return -1;
}
if (headspace + len > size) {
LOG_DBGF("Buffer too small for data.");
- return NULL;
+ return -1;
}
pthread_mutex_lock(dum->shm_mutex);
@@ -237,20 +258,20 @@ struct shm_du_buff * shm_create_du_buff(struct shm_du_map * dum,
if (sz2 < 0 && sz > 0) {
pthread_mutex_unlock(dum->shm_mutex);
LOG_DBG("Can't handle this packet now");
- return NULL;
+ return -1;
}
++blocks;
}
if (!shm_map_free(dum, blocks)) {
pthread_mutex_unlock(dum->shm_mutex);
- LOG_DBGF("Allocation failed, Out of Memory.");
- return NULL;
+ return -1;
}
sdb = get_head_ptr(dum);
sdb->size = size;
+ sdb->garbage = 0;
sdb->du_head = headspace;
sdb->du_tail = sdb->du_head + len;
@@ -267,32 +288,76 @@ struct shm_du_buff * shm_create_du_buff(struct shm_du_map * dum,
--blocks;
}
+ index = *dum->ptr_head - 1;
+
pthread_mutex_unlock(dum->shm_mutex);
- return sdb;
+ return index;
}
-int shm_release_du_buff(struct shm_du_map * dum)
+/* FIXME: this cannot handle packets stretching beyond the ringbuffer border */
+int shm_du_map_read_sdu(uint8_t ** dst,
+ struct shm_du_map * dum,
+ size_t idx)
+{
+ size_t len = 0;
+
+ if (idx > SHM_BLOCKS_IN_MAP)
+ return -1;
+
+ pthread_mutex_lock(dum->shm_mutex);
+
+ if (*dum->ptr_head == *dum->ptr_tail) {
+ pthread_mutex_unlock(dum->shm_mutex);
+ return -1;
+ }
+
+ *dst = ((uint8_t *) idx_to_du_buff_ptr(dum, idx)) +
+ sizeof(struct shm_du_buff) +
+ idx_to_du_buff_ptr(dum, idx)->du_head;
+ len = sdu_size(dum, idx);
+
+ pthread_mutex_unlock(dum->shm_mutex);
+
+ return len;
+}
+
+int shm_release_du_buff(struct shm_du_map * dum, size_t idx)
{
long sz;
long blocks = 0;
+
+ /* FIXME: this is crap for the test */
+ if (idx > SHM_BLOCKS_IN_MAP)
+ idx = *dum->ptr_tail;
+
pthread_mutex_lock(dum->shm_mutex);
if (*dum->ptr_head == *dum->ptr_tail) {
- LOG_DBGF("Attempt to free empty ringbuffer. Nothing to do.");
pthread_mutex_unlock(dum->shm_mutex);
return -1;
}
- sz = get_tail_ptr(dum)->size;
+ idx_to_du_buff_ptr(dum, idx)->garbage = 1;
- while (sz + (long) sizeof (struct shm_du_buff) > 0) {
- sz -= SHM_DU_BUFF_BLOCK_SIZE;
- ++blocks;
+ if (idx != *dum->ptr_tail) {
+ pthread_mutex_unlock(dum->shm_mutex);
+ return 0;
+ }
+
+ while (get_tail_ptr(dum)->garbage == 1) {
+ sz = get_tail_ptr(dum)->size;
+
+ while (sz + (long) sizeof (struct shm_du_buff) > 0) {
+ sz -= SHM_DU_BUFF_BLOCK_SIZE;
+ ++blocks;
+ }
+
+ *(dum->ptr_tail) =
+ (*dum->ptr_tail + blocks) & (SHM_BLOCKS_IN_MAP - 1);
}
- *(dum->ptr_tail) = (*dum->ptr_tail + blocks) & (SHM_BLOCKS_IN_MAP - 1);
pthread_mutex_unlock(dum->shm_mutex);
return 0;
@@ -317,7 +382,7 @@ uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb,
}
uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb,
- size_t size)
+ size_t size)
{
if (sdb == NULL) {
LOG_DBGF("Bogus input, bugging out.");
@@ -335,7 +400,7 @@ uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb,
}
int shm_du_buff_head_release(struct shm_du_buff * sdb,
- size_t size)
+ size_t size)
{
if (sdb == NULL) {
LOG_DBGF("Bogus input, bugging out.");
@@ -353,7 +418,7 @@ int shm_du_buff_head_release(struct shm_du_buff * sdb,
}
int shm_du_buff_tail_release(struct shm_du_buff * sdb,
- size_t size)
+ size_t size)
{
if (sdb == NULL) {
LOG_DBGF("Bogus input, bugging out.");