diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/dev.c | 221 | 
1 files changed, 68 insertions, 153 deletions
| diff --git a/src/lib/dev.c b/src/lib/dev.c index b6c6087f..43543af3 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -51,9 +51,12 @@  #define MPL 2000 /* ms */ +#ifndef CLOCK_REALTIME_COARSE +#define CLOCK_REALTIME_COARSE CLOCK_REALTIME +#endif +  struct flow_set { -        size_t idx; -        bool   np1_set; +        size_t   idx;  };  struct fqueue { @@ -71,19 +74,19 @@ enum port_state {  };  struct frcti { -        bool          used; +        bool            used; -        struct tw_f * snd_inact; -        bool          snd_drf; -        uint64_t      snd_lwe; -        uint64_t      snd_rwe; +        struct timespec last_snd; +        bool            snd_drf; +        uint64_t        snd_lwe; +        uint64_t        snd_rwe; -        struct tw_f * rcv_inact; -        bool          rcv_drf; -        uint64_t      rcv_lwe; -        uint64_t      rcv_rwe; +        struct timespec last_rcv; +        bool            rcv_drf; +        uint64_t        rcv_lwe; +        uint64_t        rcv_rwe; -        uint8_t       conf_flags; +        uint8_t         conf_flags;  };  struct port { @@ -268,27 +271,15 @@ static int frcti_init(int fd)  static void frcti_clear(int fd)  { -        struct frcti * frcti; - -        frcti = &(ai.frcti[fd]); - -        frcti->used = false; -        frcti->snd_inact = NULL; -        frcti->rcv_inact = NULL; +        ai.frcti[fd].used = false;  }  static void frcti_fini(int fd)  { -        struct frcti * frcti; - -        frcti = &(ai.frcti[fd]); - -        /* FIXME: We actually need to wait until these timers become NULL. */ -        if (frcti->snd_inact != NULL) -                timerwheel_stop(ai.tw, frcti->snd_inact); - -        if (frcti->rcv_inact != NULL) -                timerwheel_stop(ai.tw, frcti->rcv_inact); +        /* +         * FIXME: In case of reliable transmission we should +         * make sure everything is acked. +         */          frcti_clear(fd);  } @@ -304,78 +295,49 @@ static int frcti_configure(int         fd,          return 0;  } -static void frcti_snd_inactivity(void * arg) -{ -        struct frcti *  frcti; - -        pthread_rwlock_wrlock(&ai.lock); - -        frcti = (struct frcti * ) arg; - -        frcti->snd_drf = true; -        frcti->snd_inact = NULL; - -        pthread_rwlock_unlock(&ai.lock); -} - -/* Called under flows lock */  static int frcti_write(int                  fd,                         struct shm_du_buff * sdb)  {          struct frcti *  frcti;          struct frct_pci pci; +        struct timespec now = {0, 0};          memset(&pci, 0, sizeof(pci));          frcti = &(ai.frcti[fd]); -        pthread_rwlock_unlock(&ai.lock); +        clock_gettime(CLOCK_REALTIME_COARSE, &now); -        timerwheel_move(ai.tw); +        pthread_rwlock_wrlock(&ai.lock); -        pthread_rwlock_rdlock(&ai.lock); +        /* Check if sender inactivity is true. */ +        if (!frcti->snd_drf && ts_diff_ms(&now, &frcti->last_snd) > 2 * MPL) +                frcti->snd_drf = true; -        /* -         * Set the DRF in the first packet of a new run of SDUs, -         * otherwise simply recharge the timer. -         */ +        /* Set the DRF in the first packet of a new run of SDUs. */          if (frcti->snd_drf) { -                frcti->snd_inact = timerwheel_start(ai.tw, frcti_snd_inactivity, -                                                    frcti, 2 * MPL); -                if (frcti->snd_inact == NULL) -                        return -1; -                  pci.flags |= FLAG_DATA_RUN;                  frcti->snd_drf = false; -        } else { -                if (timerwheel_restart(ai.tw, frcti->snd_inact, 2 * MPL)) -                        return -1;          } +        frcti->last_snd = now; +          pci.seqno = frcti->snd_lwe++;          pci.type |= PDU_TYPE_DATA; -        if (frct_pci_ser(sdb, &pci, frcti->conf_flags & CONF_ERROR_CHECK)) +        if (frct_pci_ser(sdb, &pci, frcti->conf_flags & CONF_ERROR_CHECK)) { +                pthread_rwlock_unlock(&ai.lock);                  return -1; +        } -        if (finalize_write(fd, shm_du_buff_get_idx(sdb))) +        if (finalize_write(fd, shm_du_buff_get_idx(sdb))) { +                pthread_rwlock_unlock(&ai.lock);                  return -ENOTALLOC; - -        return 0; -} - -static void frcti_rcv_inactivity(void * arg) -{ -        struct frcti *  frcti; - -        pthread_rwlock_wrlock(&ai.lock); - -        frcti = (struct frcti * ) arg; - -        frcti->rcv_drf = true; -        frcti->rcv_inact = NULL; +        }          pthread_rwlock_unlock(&ai.lock); + +        return 0;  }  static ssize_t frcti_read(int fd) @@ -385,8 +347,7 @@ static ssize_t frcti_read(int fd)          struct frcti *       frcti;          struct frct_pci      pci;          struct shm_du_buff * sdb; - -        timerwheel_move(ai.tw); +        struct timespec      now = {0, 0};          pthread_rwlock_rdlock(&ai.lock); @@ -412,6 +373,8 @@ static ssize_t frcti_read(int fd)          if (idx < 0)                  return idx; +        clock_gettime(CLOCK_REALTIME_COARSE, &now); +          pthread_rwlock_rdlock(&ai.lock);          frcti = &(ai.frcti[fd]); @@ -425,7 +388,11 @@ static ssize_t frcti_read(int fd)                  return -EAGAIN;          } -        /* We don't accept packets when there is no inactivity timer. */ +        /* Check if receiver inactivity is true. */ +        if (!frcti->rcv_drf && ts_diff_ms(&now, &frcti->last_rcv) > 3 * MPL) +                frcti->rcv_drf = true; + +        /* We don't accept packets when there is receiver inactivity. */          if (frcti->rcv_drf && !(pci.flags & FLAG_DATA_RUN)) {                  pthread_rwlock_unlock(&ai.lock);                  shm_rdrbuff_remove(ai.rdrb, idx); @@ -433,68 +400,22 @@ static ssize_t frcti_read(int fd)          }          /* -         * If there is an inactivity timer and the DRF is set, +         * If there is no receiver inactivity and the DRF is set,           * reset the state of the connection.           */ -        if (pci.flags & FLAG_DATA_RUN) { -                frcti->rcv_drf = true; -                if (frcti->rcv_inact != NULL) -                        timerwheel_stop(ai.tw, frcti->rcv_inact); +        if (pci.flags & FLAG_DATA_RUN)                  frcti->rcv_lwe = pci.seqno; -        } - -        /* -         * Start receiver inactivity if this packet has the DRF, -         * otherwise simply restart it. -         */ -        if (frcti->rcv_drf) { -                frcti->rcv_inact = timerwheel_start(ai.tw, frcti_rcv_inactivity, -                                                    frcti, 3 * MPL); -                if (frcti->rcv_inact == NULL) { -                        pthread_rwlock_unlock(&ai.lock); -                        shm_rdrbuff_remove(ai.rdrb, idx); -                        return -EAGAIN; -                } +        if (frcti->rcv_drf)                  frcti->rcv_drf = false; -        } else { -                if (timerwheel_restart(ai.tw, frcti->rcv_inact, 3 * MPL)) { -                        pthread_rwlock_unlock(&ai.lock); -                        shm_rdrbuff_remove(ai.rdrb, idx); -                        return -EAGAIN; -                } -        } + +        frcti->last_rcv = now;          pthread_rwlock_unlock(&ai.lock);          return idx;  } -static int frcti_event_wait(struct flow_set *       set, -                            struct fqueue *         fq, -                            const struct timespec * timeout) -{ -        int ret; - -        assert(set); -        assert(fq); - -        timerwheel_move(ai.tw); - -        /* -         * FIXME: Return the fq only if a data SDU -         * for the application is available. -         */ - -        ret = shm_flow_set_wait(ai.fqset, set->idx, fq->fqueue, timeout); -        if (ret == -ETIMEDOUT) { -                fq->fqsize = 0; -                return -ETIMEDOUT; -        } - -        return ret; -} -  static void flow_clear(int fd)  {          assert(!(fd < 0)); @@ -1073,16 +994,17 @@ ssize_t flow_write(int          fd,                          shm_rdrbuff_remove(ai.rdrb, idx);                          return -ENOTALLOC;                  } + +                pthread_rwlock_unlock(&ai.lock);          } else { +                pthread_rwlock_unlock(&ai.lock); +                  if (frcti_write(fd, shm_rdrbuff_get(ai.rdrb, idx))) { -                        pthread_rwlock_unlock(&ai.lock);                          shm_rdrbuff_remove(ai.rdrb, idx);                          return -1;                  }          } -        pthread_rwlock_unlock(&ai.lock); -          return 0;  } @@ -1090,9 +1012,10 @@ ssize_t flow_read(int    fd,                    void * buf,                    size_t count)  { -        ssize_t idx = -1; -        ssize_t n; +        ssize_t   idx = -1; +        ssize_t   n;          uint8_t * sdu; +        bool      used;          if (fd < 0 || fd >= AP_MAX_FLOWS)                  return -EBADF; @@ -1104,9 +1027,11 @@ ssize_t flow_read(int    fd,                  return -ENOTALLOC;          } +        used = ai.frcti[fd].used; +          pthread_rwlock_unlock(&ai.lock); -        if (!ai.frcti[fd].used) +        if (!used)                  idx = shm_rbuff_read(ai.flows[fd].rx_rb);          else                  idx = frcti_read(fd); @@ -1146,8 +1071,6 @@ struct flow_set * flow_set_create()                  return NULL;          } -        set->np1_set = false; -          pthread_rwlock_unlock(&ai.lock);          return set; @@ -1208,7 +1131,7 @@ int flow_set_add(struct flow_set * set,          if (set == NULL)                  return -EINVAL; -        pthread_rwlock_rdlock(&ai.lock); +        pthread_rwlock_wrlock(&ai.lock);          ret = shm_flow_set_add(ai.fqset, set->idx, ai.flows[fd].port_id); @@ -1216,9 +1139,6 @@ int flow_set_add(struct flow_set * set,          for (i = 0; i < sdus; i++)                  shm_flow_set_notify(ai.fqset, ai.flows[fd].port_id); -        if (ai.frcti[fd].used) -                set->np1_set = true; -          pthread_rwlock_unlock(&ai.lock);          return ret; @@ -1230,7 +1150,7 @@ void flow_set_del(struct flow_set * set,          if (set == NULL)                  return; -        pthread_rwlock_rdlock(&ai.lock); +        pthread_rwlock_wrlock(&ai.lock);          if (ai.flows[fd].port_id >= 0)                  shm_flow_set_del(ai.fqset, set->idx, ai.flows[fd].port_id); @@ -1306,12 +1226,7 @@ int flow_event_wait(struct flow_set *       set,                  t = &abstime;          } -        if (set->np1_set) -                ret = frcti_event_wait(set, fq, t); -        else -                ret = shm_flow_set_wait(ai.fqset, set->idx, -                                        fq->fqueue, t); - +        ret = shm_flow_set_wait(ai.fqset, set->idx, fq->fqueue, t);          if (ret == -ETIMEDOUT) {                  fq->fqsize = 0;                  return -ETIMEDOUT; @@ -1524,15 +1439,15 @@ int ipcp_flow_write(int                  fd,                          pthread_rwlock_unlock(&ai.lock);                          return -ENOTALLOC;                  } + +                pthread_rwlock_unlock(&ai.lock);          } else { -                if (frcti_write(fd, sdb)) { -                        pthread_rwlock_unlock(&ai.lock); +                pthread_rwlock_unlock(&ai.lock); + +                if (frcti_write(fd, sdb))                          return -1; -                }          } -        pthread_rwlock_unlock(&ai.lock); -          return 0;  } | 
