Esempio n. 1
0
File: app.c Progetto: MurphyMc/sts
struct list_res
reachability (const struct hs *hs, uint32_t port, const uint32_t *out, int nout)
{
  struct res *in = res_create (data_file->stages + 1);
  struct list_res res = {0};
  hs_copy (&in->hs, hs);
  in->port = port;
  list_append (&queues[ntf_get_sw (in->port)], in);

  int n = data_file->ntfs - 1;
  struct tdata data[n];
  memset (data, 0, sizeof data);

  g_out = out;
  g_nout = nout;

  for (int i = 0; i < n; i++) {
    struct tdata *p = &data[i];
    p->sw = i;
    pthread_create (&p->tid, NULL, reach_thread, p);
  }
  for (int i = 0; i < n; i++) {
    pthread_join (data[i].tid, NULL);
    list_concat (&res, &data[i].res);
  }

  return res;
}
Esempio n. 2
0
void
app_add_in (const struct hs *hs, uint32_t port)
{
  struct res *in = res_create (data_file->stages + 1);
  hs_copy (&in->hs, hs);
  in->port = port;
  list_append (&queues[ntf_get_sw (in->port)], in);
}
Esempio n. 3
0
File: app.c Progetto: 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);
    }
  }
}