コード例 #1
0
ファイル: ntf.c プロジェクト: NetSys/sts
struct list_res
ntf_apply (const struct res *in, int sw)
{
  struct tf *tf = tf_get (sw + 1);

  struct list_res queue = tf_apply (tf, in, false);
  for (int i = 0; i < data_file->stages - 1; i++) {
    struct list_res nextq = {0};
    for (struct res *cur = queue.head; cur; cur = cur->next) {
      struct list_res tmp = tf_apply (tf, cur, true);
      list_concat (&nextq, &tmp);
    }
    list_res_free (&queue);
    queue = nextq;
  }

  struct res *cur = queue.head, *prev = NULL;
  while (cur) {
    int p = in->port + OUTPUT_ID;
    if (cur->port == p) list_remove (&queue, cur, prev, res_free);
    else { prev = cur; cur = cur->next; }
  }

  return queue;
}
コード例 #2
0
ファイル: app.c プロジェクト: MurphyMc/sts
static void *
reach_thread (void *vdata)
{
  struct tdata *data = vdata;
  int sw = data->sw;
  struct list_res *res = &data->res;

  const uint32_t *out = g_out;
  int nout = g_nout;
  int ntfs = data_file->ntfs - 1;

  //int count = 0, loops = 0;
  while (true) {
    struct list_res queue = {0};
    pthread_mutex_lock (&wait_lock);
    //fprintf (stderr, "%d %d\n", sw, queues[sw].n);
    while (!queues[sw].head) {
      waiters |= 1 << sw;
      if (waiters + 1 == 1 << ntfs) {
        for (int i = 0; i < ntfs; i++) {
          if (i == sw) continue;
          pthread_cond_broadcast (&conds[i]);
        }
        pthread_mutex_unlock (&wait_lock);
        return NULL;
      }

      pthread_cond_wait (&conds[sw], &wait_lock);

      if (waiters + 1 == 1 << ntfs) {
        pthread_mutex_unlock (&wait_lock);
        return NULL;
      }
      assert (waiters | (1 << sw));
    }
    queue = queues[sw];
    memset (&queues[sw], 0, sizeof queues[sw]);
    pthread_mutex_unlock (&wait_lock);

    struct res *cur;
    while ((cur = queue.head)) {
      list_pop (&queue);

      bool new_res = false;
      struct list_res nextqs[ntfs];
      memset (nextqs, 0, sizeof nextqs);

      struct list_res ntf_res = ntf_apply (cur, sw);
      struct res *ntf_cur = ntf_res.head;
      while (ntf_cur) {
        struct res *ntf_next = ntf_cur->next;
        if (!out || int_find (ntf_cur->port, out, nout)) {
          list_append (res, ntf_cur);
          ref_add (ntf_cur, cur);
          if (out) {
            ntf_cur = ntf_next;
            continue;
          }
        }

        struct list_res ttf_res = tf_apply (tf_get (0), ntf_cur, true);
        struct res *ttf_cur = ttf_res.head;
        while (ttf_cur) {
          struct res *ttf_next = ttf_cur->next;
          if (is_loop (ttf_cur->port, cur)) {
            res_free (ttf_cur);
            ttf_cur = ttf_next;
            //loops++;
            continue;
          }

          ref_add (ttf_cur, cur);
          if (out && int_find (ttf_cur->port, out, nout)) list_append (res, ttf_cur);
          else {
            int new_sw = ntf_get_sw (ttf_cur->port);
            list_append (&nextqs[new_sw], ttf_cur);
            //count++;
            new_res = true;
          }
          ttf_cur = ttf_next;
        }
        if (out) res_free (ntf_cur);
        ntf_cur = ntf_next;
      }
      res_free_mt (cur, true);

      if (!new_res) continue;
      pthread_mutex_lock (&wait_lock);
      unsigned int wake = 0;
      for (int i = 0; i < ntfs; i++) {
        if (!nextqs[i].head) continue;
        list_concat (&queues[i], &nextqs[i]);
        pthread_cond_broadcast (&conds[i]);
        wake |= 1 << i;
      }
      waiters &= ~wake;
      pthread_mutex_unlock (&wait_lock);
    }
  }
}