示例#1
0
 /// \brief Partition.
 ///
 seec::Maybe<std::size_t>
 partition(std::size_t const Left,
           std::size_t const Right,
           std::size_t const Pivot)
 {
   // Move the pivot to the end.
   swap(Pivot, Right);
   
   // Shift all elements "less than" the pivot to the left side.
   std::size_t StoreIndex = Left;
   
   for (std::size_t i = Left; i < Right; ++i) {
     // Release memory so that the compare function can access it.
     releaseMemory();
     
     // Compare the current element to the pivot.
     auto const Comparison = Compare(getElement(i), getElement(Right));
     
     // Lock memory and ensure that the compare function hasn't deallocated it.
     if (!acquireMemory())
       return seec::Maybe<std::size_t>();
           
     if (Comparison < 0) {
       swap(i, StoreIndex);
       ++StoreIndex;
     }
   }
   
   // Move pivot to its final place.
   swap(StoreIndex, Right);
   
   // Return final index of pivot.
   return StoreIndex;
 }
示例#2
0
 /// \brief Perform the binary search.
 char const *bsearch() {
   if (!ElementCount)
     return nullptr;
   
   std::size_t Min = 0;
   std::size_t Max = ElementCount - 1;
   
   while (Min <= Max) {
     std::size_t const Mid = Min + ((Max - Min) / 2);
     
     // Compare the midpoint with the key.
     releaseMemory();
     
     // Array element is always the left side of comparison, key object is
     // always the right side of comparison. Our pointer object information
     // in the shim is set according to this, so do not change.
     auto const Comparison = Compare(getElement(Mid), Key);
     
     if (!acquireMemory())
       return nullptr;
     
     if (Comparison < 0) // Mid-point is less than Key
       Min = Mid + 1;
     else if (Comparison > 0) { // Mid-point is greater than Key
       if (Mid == 0)
         return nullptr;
       
       Max = Mid - 1;
     }
     else // Mid-point is equal to Key
       return getElement(Mid);
   }
   
   return nullptr;
 }
示例#3
0
 void
 Allocator::reinitialize(void)
 {
   if (!memAllocated_)
   {
     maxAllocated_ = 0;
     acquireMemory();
   }
 }
示例#4
0
  /// \brief Perform the quicksort.
  ///
  void *operator()()
  {
    // TODO: This should be raised as a run-time error.
    assert(CompareFn && "Comparison function is unknown!");

    auto const Caller = ThreadListener.getActiveFunction();
    assert(Caller && !Caller->isShim());

    auto const Call = llvm::ImmutableCallSite(Caller->getActiveInstruction());
    auto const KeyPtrObj   = Caller->getPointerObject(Call.getArgument(0));
    auto const ArrayPtrObj = Caller->getPointerObject(Call.getArgument(1));

    ThreadListener.pushShimFunction();
    auto const Shim = ThreadListener.getActiveFunction();

    // Array element is always the left side of comparison, key object is
    // always the right side of comparison.
    auto CompareFnArg = CompareFn->arg_begin();
    Shim->setPointerObject(  &*CompareFnArg, ArrayPtrObj);
    Shim->setPointerObject(&*++CompareFnArg, KeyPtrObj  );

    acquireMemory();
    auto const Result = bsearch();
    releaseMemory();

    ThreadListener.popShimFunction();

    // The C standard specifies the result is not const.
    auto const Unqualified = const_cast<char *>(Result);

    // Notify of the returned pointer (and its pointer object).
    auto const CallInst = Call.getInstruction();
    auto const Idx = seec::trace::getThreadEnvironment().getInstructionIndex();

    ThreadListener.notifyValue(Idx, CallInst,
                               reinterpret_cast<void *>(Unqualified));

    // Note that Caller is invalidated when the shim function is pushed, so we
    // need to retrieve a new pointer to the active function.
    ThreadListener.getActiveFunction()
                  ->setPointerObject(CallInst,
                                     Result ? ArrayPtrObj
                                            : seec::trace::PointerTarget{});

    // const_cast due to the C standard.
    return Unqualified;
  }
示例#5
0
  Allocator::Allocator(ByteCount bufferSize, UInt32 memoryQuotaMB,
                       BufferCount nBuffers, BufferCount reserve, 
                       NAMemory* heap, ExExeStmtGlobals* exeGlobals,
                       bool yieldQuota)
    : 
      maxAllocated_(0), memAllocated_(0), quota_(0), exeGlobals_(exeGlobals),
      heap_(heap), bufferSize_(bufferSize), nInitial_(nBuffers),
      nReserve_(reserve), reuseList_(heap), yieldQuota_(yieldQuota)
  {
    quotaInitial_ = memoryQuotaMB * ONE_MEGABYTE;

    if (quotaInitial_)
    {
      ex_assert(((bufferSize_ * nInitial_) <= quotaInitial_),
                "inconsistent constructor arguments");
    }
    ex_assert((nInitial_ >= nReserve_), "reserve > initial buffer count");

    acquireMemory();
  }
示例#6
0
  /// \brief Perform the quicksort.
  ///
  void operator()()
  {
    // TODO: This should be raised as a run-time error.
    assert(CompareFn && "Comparison function is unknown!");

    auto const Caller = ThreadListener.getActiveFunction();
    assert(Caller && !Caller->isShim());

    auto const Call = llvm::ImmutableCallSite(Caller->getActiveInstruction());
    auto const ArrayPtrObj = Caller->getPointerObject(Call.getArgument(0));

    ThreadListener.pushShimFunction();
    auto const Shim = ThreadListener.getActiveFunction();

    auto CompareFnArg = CompareFn->arg_begin();
    Shim->setPointerObject(  &*CompareFnArg, ArrayPtrObj);
    Shim->setPointerObject(&*++CompareFnArg, ArrayPtrObj);

    acquireMemory();
    quicksort(0, ElementCount - 1);
    releaseMemory();

    ThreadListener.popShimFunction();
  }