示例#1
0
c4snet_data_t *C4SNetShallowCopy(c4snet_data_t *data)
{
#if HAVE_SYNC_ATOMIC_BUILTINS
  /* Temporary fix for race condition: */
  AAF(&data->ref_count, 1);
#else
  /* Old code, which contains a race condition: */
  data->ref_count++;
#endif
  return data;
}
示例#2
0
/* Scan other workers for stealable items */
static bool SNetWorkerSteal(worker_t *thief)
{
  int           i;

  assert(thief->loot.desc == NULL);
  assert(thief->loot.item == NULL);

  for (i = 0; i < snet_worker_count && !thief->loot.desc; ++i) {
    thief->victim_id = 1 + (thief->victim_id % snet_worker_count);
    if (thief->victim_id != thief->id) {
      worker_t *victim = snet_workers[thief->victim_id];
      if (victim && trylock_worker(victim, thief)) {
        AAF(&victim->steal_turn->turn, 1);
        SNetWorkerStealVictim(victim, thief);
        AAF(&victim->steal_turn->turn, 1);
        unlock_worker(victim, thief);
      }
    }
  }

  return (thief->loot.desc != NULL);
}
示例#3
0
文件: xstream.c 项目: ra-one/snet-rts
/* Merge a stream to an identity landing with the subsequent stream. */
static snet_stream_desc_t *SNetMergeStreams(snet_stream_desc_t **desc_ptr)
{
  snet_stream_desc_t    *desc = *desc_ptr;
  snet_stream_desc_t    *next = DESC_LAND_SPEC(desc, identity)->outdesc;
  fifo_node_t           *fifo_tail_start;
  fifo_node_t           *fifo_tail_end;
  fifo_node_t           *node;
  int                    count = 0;

  /* Remove all data from the queue towards the garbage landing. */
  fifo_tail_start = SNetFifoGetTail(&desc->fifo, &fifo_tail_end);

  /* Count the number of data items in the captured list. */
  for (node = fifo_tail_start; node; node = node->next) {
    ++count;
  }

  /* Append the captured list onto the subsequent stream. */
  SNetFifoPutTail(&next->fifo, fifo_tail_start, fifo_tail_end);

  /* Reconnect the source landing of the next landing. */
  next->source = desc->source;

  /* Increase the reference count by the number of added records. */
  AAF(&(next->refs), count);

  /* Report statistics. */
  if (SNetDebug()) {
    printf("%s: collecting %d recs, %d drefs, %d nrefs\n",
            __func__, count, desc->refs, next->refs);
  }

  /* Convert the identity landing into garbage. */
  SNetBecomeGarbage(desc->landing);

  /* Make sure no one ever attempts to write to the dissolved stream. */
  *desc_ptr = next;

  /* Unlock the garbage landing: some worker todo items may still need it. */
  unlock_landing(desc->landing);

  /* Decrease reference count to the garbage collected stream. */
  SNetDescDone(desc);

  /* Return the subsequent stream. */
  return next;
}
示例#4
0
/* Process a stolen item. */
static void SNetWorkerLoot(worker_t *worker)
{
  if (worker->loot.desc) {
    if (worker->loot.item) {
      if (worker->loot.count > 0) {
        AAF(&(worker->loot.item->count), worker->loot.count);
      }
      if (trylock_work_item(worker->loot.item, worker)) {
        if (worker->loot.item->count > 0) {
          SNetWorkerWorkItem(worker->loot.item, worker);
        }
        if (worker->loot.item->lock == worker->id) {
          unlock_work_item(worker->loot.item, worker);
        }
      }
    }
    else /* (worker->loot.item == NULL) */ {
      work_item_t *item = GetFreeWorkItem(worker);
      item->next_item = NULL;
      item->next_free = NULL;
      item->desc = worker->loot.desc;
      item->lock = worker->id;
      item->count = worker->loot.count;
      SNetHashPtrStore(worker->hash_ptab, item->desc, item);
      SNetWorkerWorkItem(item, worker);
      if (item->count == 0) {
        if (item->desc) {
          SNetHashPtrRemove(worker->hash_ptab, item->desc);
        }
        item->lock = worker->id;
        PutFreeWorkItem(worker, item);
      } else {
        item->lock = 0;
        item->next_item = worker->prev->next_item;
        BAR();
        worker->prev->next_item = worker->iter = item;
      }
    }
    worker->loot.desc = NULL;
    worker->loot.count = 0;
    worker->loot.item = NULL;
    worker->has_work = (worker->todo.head.next_item != NULL);
  }
}
示例#5
0
/* Add a new unit of work to the worker's todo list.
 * At return iterator should point to the new item.
 */
void SNetWorkerTodo(worker_t *worker, snet_stream_desc_t *desc)
{
  work_item_t   *item = SNetHashPtrLookup(worker->hash_ptab, desc);

  if (item) {
    /* Item may be locked by a thief. */
    AAF(&item->count, 1);
  } else {
    item = GetFreeWorkItem(worker);
    item->count = 1;
    item->desc = desc;
    item->lock = 0;
    item->next_free = NULL;
    item->next_item = worker->prev->next_item;
    BAR();
    worker->prev->next_item = item;
    worker->prev = item;
    SNetHashPtrStore(worker->hash_ptab, desc, item);
    worker->has_work = true;
  }
}
示例#6
0
AAF sin(const AAF & P)
{
    if(P.is_infinite())
        return AAF(interval(-1,1));
    interval i = P.convert();

    double w = i.width();

    const double a = i.left();
    const double b = i.right();


    // y' = alpha*x+dzeta , the regression line
    // approximate y = sin(x)

    double alpha, dzeta, delta;

    if (w >= 2*PI ) {
// the trivial case, the interval is larger than 2*PI
        // y' = 0 , delta = 1 cause -1 <= sin(x) <= +1
        return AAF(interval(-1,1));
        alpha = 0.0;
        dzeta = 0.0;
        delta = 1.0;
    } else {
// case of the least squares
        double x[NPTS];
        double y[NPTS];
        double r[NPTS]; // residues, r[i] = y[i]-y'[i]

        x[0] = a;
        y[0] = sin(a);
        x[NPTS-1] = b;
        y[NPTS-1] = sin(b);

        double pas = w/(NPTS-1);

        for (unsigned i=1; i< NPTS-1; i++) {
            x[i] = x[i-1]+pas;
            y[i] = sin(x[i]);
        }


        // Calculation of xm and ym , averages of x and y

        double xm = 0;
        double ym = 0;

        for (unsigned i=0; i<NPTS; i++) {
            xm = xm + x[i];
            ym = ym + y[i];
        }

        xm = xm/NPTS;
        ym = ym/NPTS;

        // Calculation of alpha and dzeta

        double temp2 = 0;
        alpha = 0;

        for (unsigned i = 0; i < NPTS; i++) {
            const double temp1 = x[i] - xm;
            alpha += y[i]*temp1;
            temp2 += temp1*temp1;
        }

        alpha = alpha/temp2;  // final alpha
        dzeta = ym - alpha*xm; // final dzeta


        // Calculation of the residues
        // We use the absolute value of the residues!

        for (unsigned i = 0; i < NPTS; i++) {
            r[i] = fabs(y[i] - (dzeta+alpha*x[i]));
        }


        // The error delta is the maximum
        // of the residues (in absolute values)

        delta = *std::max_element(r, r+NPTS);
    }


    return AAF(P, alpha, dzeta, delta, P.special);
}
示例#7
0
/* Work on an item.
 *
 * In case of a dissolved garbage stream update the source
 * stream of the work item.
 *
 * Return true iff a record was processed.
 *
 * If the contents of the item was merged with another item then
 * reset the item descriptor to NULL.
 */
static bool SNetWorkerWorkItem(work_item_t *const item, worker_t *worker)
{
  work_item_t           *lookup;

  /* Item must be owned and non-empty. */
  assert(item->lock == worker->id);
  assert(item->count > 0);

  /* Claim destination landing. */
  if (trylock_landing(item->desc->landing, worker) == false) {
    /* Nothing can be done. */
    return false;
  }

  /* Bring item descriptors past any garbage collectable landings. */
  while (item->desc->landing->type == LAND_garbage) {
    /* Get subsequent descriptor. */
    snet_stream_desc_t *next_desc = DESC_LAND_SPEC(item->desc, siso)->outdesc;

    /* Release landing claim. */
    unlock_landing(item->desc->landing);

    /* Decrease reference counts to descriptor. */
    SNetDescRelease(item->desc, item->count);

    /* Take item out of hash table. */
    SNetHashPtrRemove(worker->hash_ptab, item->desc);

    /* Update item descriptor. */
    item->desc = next_desc;

    /* Also advance past subsequent garbage landings. */
    while (next_desc->landing->type == LAND_garbage) {

      /* Get subsequent descriptor. */
      item->desc = DESC_LAND_SPEC(next_desc, siso)->outdesc;

      /* Test if current descriptor is also in our hash table. */
      lookup = (work_item_t *)SNetHashPtrLookup(worker->hash_ptab, next_desc);
      if (lookup && trylock_work_item(lookup, worker)) {
        /* Merge both descriptor counts into one. */
        item->count += lookup->count;
        lookup->count = 0;
        unlock_work_item(lookup, worker);
      }

      /* Decrease reference counts to garbage descriptor. */
      SNetDescRelease(next_desc, item->count);

      /* Advance to subsequent descriptor and repeat. */
      next_desc = item->desc;
    }

    /* The new descriptor may already exist in hash table. */
    lookup = (work_item_t *)SNetHashPtrLookup(worker->hash_ptab, next_desc);
    if (lookup) {
      /* Merge the two counts. */
      AAF(&lookup->count, item->count);
      /* Reset item. */
      item->count = 0;
      /* We already have this desciptor in lookup, so reset it. */
      item->desc = NULL;
      /* We made progress. */
      return true;
    }
    else /* (lookup == NULL) */ {

      /* Add new descriptor to hash table. */
      SNetHashPtrStore(worker->hash_ptab, item->desc, item);

      /* Claim destination landing. */
      if (trylock_landing(item->desc->landing, worker) == false) {
        /* We made progress anyway. */
        return true;
      }
    }
  }

  /* Subtract one read license. */
  --item->count;

  /* Unlock item so thieves can steal it while we work. */
  unlock_work_item(item, worker);

  /* Finally, do the work by delegating to the streams layer. */
  SNetStreamWork(item->desc, worker);

  /* We definitely made progress. */
  return true;
}