diff options
| -rw-r--r-- | include/ouroboros/shm_du_map.h | 24 | ||||
| -rw-r--r-- | src/lib/shm_du_map.c | 124 | 
2 files changed, 103 insertions, 45 deletions
| diff --git a/include/ouroboros/shm_du_map.h b/include/ouroboros/shm_du_map.h index 23c0c3aa..11fe35c6 100644 --- a/include/ouroboros/shm_du_map.h +++ b/include/ouroboros/shm_du_map.h @@ -50,16 +50,18 @@ int       shm_du_map_read(uint8_t **          dst,                            struct shm_du_map * dum,                            ssize_t             idx);  int       shm_du_map_remove(struct shm_du_map  * dum, -                            ssize_t idx); - -/* FIXME: use shm_du_map * and index */ -uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb, -                                 size_t size); -uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb, -                                 size_t size); -int       shm_du_buff_head_release(struct shm_du_buff * sdb, -                                   size_t size); -int       shm_du_buff_tail_release(struct shm_du_buff * sdb, -                                   size_t size); +                            ssize_t              idx); +uint8_t * shm_du_buff_head_alloc(struct shm_du_map * dum, +                                 int                 idx, +                                 ssize_t             size); +uint8_t * shm_du_buff_tail_alloc(struct shm_du_map * dum, +                                 int                 idx, +                                 ssize_t             size); +int       shm_du_buff_head_release(struct shm_du_map * dum, +                                   int                 idx, +                                   ssize_t             size); +int       shm_du_buff_tail_release(struct shm_du_map * dum, +                                   int                 idx, +                                   ssize_t             size);  #endif /* OUROBOROS_SHM_DU_MAP_H */ diff --git a/src/lib/shm_du_map.c b/src/lib/shm_du_map.c index 6a4b7361..9d2d4f6e 100644 --- a/src/lib/shm_du_map.c +++ b/src/lib/shm_du_map.c @@ -413,8 +413,7 @@ ssize_t shm_du_map_write(struct shm_du_map * dum,  #ifdef SHM_DU_MAP_MULTI_BLOCK          long                 blocks = 0;          long                 padblocks = 0; -        int                  sz = headspace + len + sizeof *sdb; -        int                  sz2 = sz + tailspace; +        int                  sz = size + sizeof *sdb;  #endif          uint8_t *            write_pos;          ssize_t              index = -1; @@ -425,7 +424,7 @@ ssize_t shm_du_map_write(struct shm_du_map * dum,          }  #ifndef SHM_DU_MAP_MULTI_BLOCK -        if (size + sizeof *sdb > SHM_DU_BUFF_BLOCK_SIZE) { +        if (sz > SHM_DU_BUFF_BLOCK_SIZE) {                  LOG_DBGF("Multi-block SDU's disabled. Dropping.");                  return -1;          } @@ -435,14 +434,8 @@ ssize_t shm_du_map_write(struct shm_du_map * dum,                  pthread_mutex_consistent(dum->shm_mutex);          }  #ifdef SHM_DU_MAP_MULTI_BLOCK -        while (sz2 > 0) { -                sz2 -= SHM_DU_BUFF_BLOCK_SIZE; +        while (sz > 0) {                  sz -= SHM_DU_BUFF_BLOCK_SIZE; -                if (sz < 0 && sz2 > 0) { -                        pthread_mutex_unlock(dum->shm_mutex); -                        LOG_DBG("Can't handle this packet now."); -                        return -EAGAIN; -                }                  ++blocks;          } @@ -478,7 +471,7 @@ ssize_t shm_du_map_write(struct shm_du_map * dum,  #ifdef  SHM_DU_MAP_MULTI_BLOCK          sdb->blocks  = blocks;  #endif -        write_pos = ((uint8_t *) sdb) + sizeof *sdb + headspace; +        write_pos = ((uint8_t *) (sdb + 1)) + headspace;          memcpy(write_pos, data, len); @@ -515,7 +508,7 @@ int shm_du_map_read(uint8_t **          dst,          sdb = idx_to_du_buff_ptr(dum, idx);          len = sdb->du_tail - sdb->du_head; -        *dst = ((uint8_t *) sdb) + sizeof(struct shm_du_buff) + sdb->du_head; +        *dst = ((uint8_t *) (sdb + 1)) + sdb->du_head;          pthread_mutex_unlock(dum->shm_mutex); @@ -547,6 +540,7 @@ int shm_du_map_remove(struct shm_du_map * dum, ssize_t idx)          garbage_collect(dum);          *dum->choked = 0; +          pthread_cond_signal(dum->healthy);          pthread_mutex_unlock(dum->shm_mutex); @@ -554,74 +548,136 @@ int shm_du_map_remove(struct shm_du_map * dum, ssize_t idx)          return 0;  } -uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb, -                                 size_t size) +uint8_t * shm_du_buff_head_alloc(struct shm_du_map * dum, +                                 int                 idx, +                                 ssize_t             size)  { -        if (sdb == NULL) { -                LOG_DBGF("Bogus input, bugging out."); +        struct shm_du_buff * sdb; +        uint8_t * buf; + +        if (dum  == NULL) +                return NULL; + +        if (idx < 0 || idx > SHM_BLOCKS_IN_MAP)                  return NULL; + +        if (pthread_mutex_lock(dum->shm_mutex) == EOWNERDEAD) { +                LOG_DBGF("Recovering dead mutex."); +                pthread_mutex_consistent(dum->shm_mutex);          } +        sdb = idx_to_du_buff_ptr(dum, idx); +          if ((long) (sdb->du_head - size) < 0) { +                pthread_mutex_unlock(dum->shm_mutex);                  LOG_DBGF("Failed to allocate PCI headspace.");                  return NULL;          }          sdb->du_head -= size; -        return (uint8_t *) sdb + sizeof *sdb + sdb->du_head; +        buf = (uint8_t *) (sdb + 1) + sdb->du_head; + +        pthread_mutex_unlock(dum->shm_mutex); + +        return buf;  } -uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb, -                                 size_t               size) +uint8_t * shm_du_buff_tail_alloc(struct shm_du_map * dum, +                                 int                 idx, +                                 ssize_t             size)  { -        if (sdb == NULL) { -                LOG_DBGF("Bogus input, bugging out."); +        struct shm_du_buff * sdb; +        uint8_t * buf; + +        if (dum  == NULL)                  return NULL; + +        if (idx < 0 || idx > SHM_BLOCKS_IN_MAP) +                return NULL; + +        if (pthread_mutex_lock(dum->shm_mutex) == EOWNERDEAD) { +                LOG_DBGF("Recovering dead mutex."); +                pthread_mutex_consistent(dum->shm_mutex);          } +        sdb = idx_to_du_buff_ptr(dum, idx); +          if (sdb->du_tail + size >= sdb->size) { +                pthread_mutex_unlock(dum->shm_mutex);                  LOG_DBGF("Failed to allocate PCI tailspace.");                  return NULL;          } +        buf = (uint8_t *) (sdb + 1) + sdb->du_tail; +          sdb->du_tail += size; -        return (uint8_t *) sdb + sizeof *sdb + sdb->du_tail; +        pthread_mutex_unlock(dum->shm_mutex); + +        return buf;  } -int shm_du_buff_head_release(struct shm_du_buff * sdb, -                             size_t               size) +int shm_du_buff_head_release(struct shm_du_map * dum, +                             int                 idx, +                             ssize_t             size)  { -        if (sdb == NULL) { -                LOG_DBGF("Bogus input, bugging out."); -                return -EINVAL; +        struct shm_du_buff * sdb; + +        if (dum  == NULL) +                return -1; + +        if (idx < 0 || idx > SHM_BLOCKS_IN_MAP) +                return -1; + +        if (pthread_mutex_lock(dum->shm_mutex) == EOWNERDEAD) { +                LOG_DBGF("Recovering dead mutex."); +                pthread_mutex_consistent(dum->shm_mutex);          } +        sdb = idx_to_du_buff_ptr(dum, idx); +          if (size > sdb->du_tail - sdb->du_head) { +                pthread_mutex_unlock(dum->shm_mutex);                  LOG_DBGF("Tried to release beyond sdu boundary.");                  return -EOVERFLOW;          }          sdb->du_head += size; -        return sdb->du_head; +        pthread_mutex_unlock(dum->shm_mutex); + +        return 0;  } -int shm_du_buff_tail_release(struct shm_du_buff * sdb, -                             size_t               size) +int shm_du_buff_tail_release(struct shm_du_map * dum, +                             int                 idx, +                             ssize_t             size)  { -        if (sdb == NULL) { -                LOG_DBGF("Bogus input, bugging out."); -                return -EINVAL; +        struct shm_du_buff * sdb; + +        if (dum  == NULL) +                return -1; + +        if (idx < 0 || idx > SHM_BLOCKS_IN_MAP) +                return -1; + +        if (pthread_mutex_lock(dum->shm_mutex) == EOWNERDEAD) { +                LOG_DBGF("Recovering dead mutex."); +                pthread_mutex_consistent(dum->shm_mutex);          } +        sdb = idx_to_du_buff_ptr(dum, idx); +          if (size > sdb->du_tail - sdb->du_head) { +                pthread_mutex_unlock(dum->shm_mutex);                  LOG_DBGF("Tried to release beyond sdu boundary.");                  return -EOVERFLOW;          }          sdb->du_tail -= size; -        return sdb->du_tail; +        pthread_mutex_unlock(dum->shm_mutex); + +        return 0;  } | 
