Пример #1
0
    void execute()
    {
        Futures inputFutures;
        for (const auto& namePort : _inputMap)
        {
            const Futures& futures = namePort.second.getFutures();
            for (const auto& future : futures)
                inputFutures.emplace_back(future, namePort.second.getName());
        }

        const FutureMap futures(inputFutures);
        PromiseMap promises(getOutputPromises());

        try
        {
            _filter->execute(futures, promises);
            promises.flush();
        }
        catch (const std::runtime_error& err)
        {
            promises.flush();
            throw err;
        }
        catch (const std::logic_error& err)
        {
            promises.flush();
            throw err;
        }
    }
Пример #2
0
// static
already_AddRefed<Promise>
Promise::All(const GlobalObject& aGlobal,
             const nsTArray<RefPtr<Promise>>& aPromiseList, ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global;
  global = do_QueryInterface(aGlobal.GetAsSupports());
  if (!global) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  JSContext* cx = aGlobal.Context();

  JS::AutoObjectVector promises(cx);
  if (!promises.reserve(aPromiseList.Length())) {
    aRv.NoteJSContextException(cx);
    return nullptr;
  }

  for (auto& promise : aPromiseList) {
    JS::Rooted<JSObject*> promiseObj(cx, promise->PromiseObj());
    // Just in case, make sure these are all in the context compartment.
    if (!JS_WrapObject(cx, &promiseObj)) {
      aRv.NoteJSContextException(cx);
      return nullptr;
    }
    promises.infallibleAppend(promiseObj);
  }

  JS::Rooted<JSObject*> result(cx, JS::GetWaitForAllPromise(cx, promises));
  if (!result) {
    aRv.NoteJSContextException(cx);
    return nullptr;
  }

  return CreateFromExisting(global, result);
}
Пример #3
0
folly::Future<bool> Barrier::wait() {
  // Load the current control block first. As we know there is at least
  // one thread in the current epoch (us), this means that the value is
  // < size_, so controlBlock_ can't change until we bump the value below.
  auto block = controlBlock_.load(std::memory_order_acquire);
  auto p = promises(block);

  // Bump the value and record ourselves as reader.
  // This ensures that block stays allocated, as the reader count is > 0.
  auto prev = block->valueAndReaderCount.fetch_add(
      kReader + 1, std::memory_order_acquire);

  auto prevValue = static_cast<uint32_t>(prev & kValueMask);
  DCHECK_LT(prevValue, size_);
  auto future = p[prevValue].getFuture();

  if (prevValue + 1 == size_) {
    // Need to reset the barrier before fulfilling any futures. This is
    // when the epoch is flipped to the next.
    controlBlock_.store(allocateControlBlock(), std::memory_order_release);

    p[0].setValue(true);
    for (uint32_t i = 1; i < size_; ++i) {
      p[i].setValue(false);
    }
  }

  // Free the control block if we're the last reader at max value.
  prev =
      block->valueAndReaderCount.fetch_sub(kReader, std::memory_order_acq_rel);
  if (prev == (kReader | uint64_t(size_))) {
    freeControlBlock(block);
  }

  return future;
}
Пример #4
0
int main(int argc, const char * argv[])
{
    promises();

    return 0;
}
void CPUUncontrolledApproximation::perform() {
    const auto &ctx = kernel->context();
    auto &stateModel = kernel->getCPUKernelStateModel();
    auto nl = stateModel.getNeighborList();
    auto &data = nl->data();
    const auto &box = ctx.boxSize().data();
    const auto &pbc = ctx.periodicBoundaryConditions().data();

    if (ctx.recordReactionsWithPositions()) {
        kernel->getCPUKernelStateModel().reactionRecords().clear();
    }
    if (ctx.recordReactionCounts()) {
        stateModel.resetReactionCounts();
    }

    // gather events
    std::vector<std::promise<std::size_t>> n_events_promises(kernel->getNThreads());
    std::vector<event_promise_t> promises(kernel->getNThreads());
    {

        auto &pool = kernel->pool();

        std::vector<std::function<void(std::size_t)>> executables;
        executables.reserve(kernel->getNThreads());

        std::size_t grainSize = data.size() / kernel->getNThreads();
        std::size_t nlGrainSize = nl->nCells() / kernel->getNThreads();

        auto it = data.cbegin();
        std::size_t it_nl = 0;
        for (auto i = 0U; i < kernel->getNThreads()-1 ; ++i) {
            auto itNext = std::min(it+grainSize, data.cend());

            auto nlNext = std::min(it_nl + nlGrainSize, nl->nCells());
            auto bounds_nl = std::make_tuple(it_nl, nlNext);

            pool.push(findEvents, it, itNext, bounds_nl, kernel, timeStep(), false, std::cref(*nl),
                      std::ref(promises.at(i)), std::ref(n_events_promises.at(i)));

            it = itNext;
            it_nl = nlNext;
        }
        pool.push(findEvents, it, data.cend(), std::make_tuple(it_nl, nl->nCells()), kernel, timeStep(), false,
                  std::cref(*nl), std::ref(promises.back()), std::ref(n_events_promises.back()));
    }

    // collect events
    std::vector<event_t> events;
    {
        std::size_t n_events = 0;
        for (auto &&f : n_events_promises) {
            n_events += f.get_future().get();
        }
        events.reserve(n_events);
        for (auto &&f : promises) {
            auto eventUpdate = std::move(f.get_future().get());
            auto mBegin = std::make_move_iterator(eventUpdate.begin());
            auto mEnd = std::make_move_iterator(eventUpdate.end());
            events.insert(events.end(), mBegin, mEnd);
        }
    }

    // shuffle reactions
    std::shuffle(events.begin(), events.end(), std::mt19937(std::random_device()()));

    // execute reactions
    {
        data_t::EntriesUpdate newParticles{};
        std::vector<data_t::size_type> decayedEntries{};

        // todo better conflict detection?
        for (auto it = events.begin(); it != events.end(); ++it) {
            auto &event = *it;
            if (event.cumulativeRate == 0) {
                auto entry1 = event.idx1;
                if (event.nEducts == 1) {
                    auto reaction = ctx.reactions().order1ByType(event.t1)[event.reactionIndex];
                    if (ctx.recordReactionsWithPositions()) {
                        record_t record;
                        record.id = reaction->id();
                        performReaction(&data, ctx, entry1, entry1, newParticles, decayedEntries, reaction, &record);
                        bcs::fixPosition(record.where, box, pbc);
                        kernel->getCPUKernelStateModel().reactionRecords().push_back(record);
                    } else {
                        performReaction(&data, ctx, entry1, entry1, newParticles, decayedEntries, reaction, nullptr);
                    }
                    if (ctx.recordReactionCounts()) {
                        auto &counts = stateModel.reactionCounts();
                        counts.at(reaction->id())++;
                    }
                    for (auto _it2 = it + 1; _it2 != events.end(); ++_it2) {
                        if (_it2->idx1 == entry1 || _it2->idx2 == entry1) {
                            _it2->cumulativeRate = 1;
                        }
                    }
                } else {
                    auto reaction = ctx.reactions().order2ByType(event.t1, event.t2)[event.reactionIndex];
                    if (ctx.recordReactionsWithPositions()) {
                        record_t record;
                        record.id = reaction->id();
                        performReaction(&data, ctx, entry1, event.idx2, newParticles, decayedEntries, reaction, &record);
                        bcs::fixPosition(record.where, box, pbc);
                        kernel->getCPUKernelStateModel().reactionRecords().push_back(record);
                    } else {
                        performReaction(&data, ctx, entry1, event.idx2, newParticles, decayedEntries, reaction, nullptr);
                    }
                    if (ctx.recordReactionCounts()) {
                        auto &counts = stateModel.reactionCounts();
                        counts.at(reaction->id())++;
                    }
                    for (auto _it2 = it + 1; _it2 != events.end(); ++_it2) {
                        if (_it2->idx1 == entry1 || _it2->idx2 == entry1 ||
                            _it2->idx1 == event.idx2 || _it2->idx2 == event.idx2) {
                            _it2->cumulativeRate = 1;
                        }
                    }
                }
            }
        }
        data.update(std::make_pair(std::move(newParticles), std::move(decayedEntries)));
    }
}