Example #1
0
void    GCAllocator::InternalFree(AllocStructure * freedPtr, int alignedSize)
{
    CROSSNET_ASSERT(IsAligned(freedPtr), "");
    CROSSNET_ASSERT(IsAligned(alignedSize), "");

    freedPtr->mMarker = FREE_MARKER;
    freedPtr->mSize = alignedSize;

/*
    if (alignedSize <= SMALL_SIZE_BIN)
    {
        // Deallocation that happens most of the time
        int indexSmallBin = alignedSize >> ALIGNMENT_SHIFT;
        freedPtr->mNext = sSmallBin[indexSmallBin];
        sSmallBin[indexSmallBin] = freedPtr;
    }
    else
*/
    {
        // Do not use next power of 2 here, as this should be greater than the size we are looking for
        int newTopBit = TopBit(alignedSize + 1);        // Increment so if the size is exactly a poer of two, the bit will stay in the same range
        --newTopBit;                                    // But will write one level below as the size is guaranteed to be at least in the range we are looking

        CROSSNET_ASSERT(alignedSize >= (1 << newTopBit), "");       // Check that the range is correct...
        CROSSNET_ASSERT(alignedSize < (1 << (newTopBit + 1)), "");

        freedPtr->mNext = sMediumBin[newTopBit];
        sMediumBin[newTopBit] = freedPtr;
    }
}
Example #2
0
HRESULT
CAsyncIo::SyncRead(
            LONGLONG llPos,
            LONG lLength,
            BYTE* pBuffer)
{
    if (IsAligned(llPos) &&
	IsAligned(lLength) &&
	IsAligned((LONG) pBuffer)) {
            LONG cbUnused;
	    return SyncReadAligned(llPos, lLength, pBuffer, &cbUnused, NULL);
    }

    
    

    CAsyncRequest request;

    HRESULT hr = request.Request(
                    this,
                    m_pStream,
                    llPos,
                    lLength,
                    FALSE,
                    pBuffer,
                    NULL,
                    0);

    if (FAILED(hr)) {
        return hr;
    }

    return request.Complete();
}
Example #3
0
STDMETHODIMP CRFSOutputPin::SyncReadAligned (IMediaSample* pSample)
{
    LONGLONG llPosition;
    DWORD lLength;
    BYTE* pBuffer;

    if (!m_file)
    {
        DbgLog((LOG_TRACE, 2, L"SyncReadAligned called with no file loaded."));
        return E_UNEXPECTED;
    }

    HRESULT hr = ConvertSample (pSample, &llPosition, &lLength, &pBuffer);

    if (FAILED (hr))
        return hr;

    if (!(IsAligned ((INT_PTR) llPosition) && IsAligned ((INT_PTR) lLength) && IsAligned ((INT_PTR) pBuffer)))
    {
        DbgLog((LOG_TRACE, 2, L"SyncReadAligned bad alignment. align = %lu, pos = %lld, len = %lu, buf = %p",
                m_align, llPosition, lLength, pBuffer));
        return VFW_E_BADALIGN;
    }

    LONG cbActual = 0;

    hr = m_file->SyncRead (llPosition, lLength, pBuffer, &cbActual);

    pSample->SetActualDataLength (cbActual);

    return hr;
}
Example #4
0
// perform a synchronous read request on this thread.
// may not be aligned - so we will have to buffer.
HRESULT
CAsyncIo::SyncRead(
                LONGLONG llPos,
                LONG lLength,
                BYTE * pBuffer)
{
    if(IsAligned(llPos) &&
        IsAligned(lLength) &&
        IsAligned((LONG_PTR) pBuffer))
    {
        LONG cbUnused;
        return SyncReadAligned(llPos, lLength, pBuffer, &cbUnused, NULL);
    }

    // not aligned with requirements - use buffered file handle.
    //!!! might want to fix this to buffer the data ourselves?

    CAsyncRequest request;

    HRESULT hr = request.Request(this,
                                m_pStream,
                                llPos,
                                lLength,
                                FALSE,
                                pBuffer,
                                NULL,
                                0);

    if(FAILED(hr))
    {
        return hr;
    }

    return request.Complete();
}
Example #5
0
    static std::complex<double> ZDot(int n, const double* A, const std::complex<double>* B)
    {
        if (n) {
#ifdef __SSE2__
            std::complex<double> sum(0);
            while (n && !IsAligned(A) ) {
                sum += *A * *B;
                ++A;
                Maybe<!c2>::increment(B);
                --n;
            }

            int n_2 = (n>>1);
            int nb = n-(n_2<<1);

            if (n_2) {
                union { __m128d xm; double xd[2]; } xsum;
                xsum.xm = _mm_set1_pd(0.);
                __m128d xsum2 = _mm_set1_pd(0.);
                const std::complex<double>* B1 = Maybe<!c2>::plus(B,1);
                assert(IsAligned(A));
                assert(IsAligned(B));
                do {
                    const __m128d& xA = *(const __m128d*)(A);
                    const __m128d& xB1 = *(const __m128d*)(B);
                    const __m128d& xB2 = *(const __m128d*)(B1);
                    A += 2;
                    Maybe<!c2>::increment(B,2);
                    Maybe<!c2>::increment(B1,2);
                    __m128d xA1 = _mm_shuffle_pd(xA,xA,_MM_SHUFFLE2(0,0));
                    __m128d xA2 = _mm_shuffle_pd(xA,xA,_MM_SHUFFLE2(1,1));
                    __m128d x1 = _mm_mul_pd(xA1,xB1);
                    __m128d x2 = _mm_mul_pd(xA2,xB2);
                    xsum.xm = _mm_add_pd(xsum.xm,x1);
                    xsum2 = _mm_add_pd(xsum2,x2);
                } while (--n_2);
                xsum.xm = _mm_add_pd(xsum.xm,xsum2);
                sum += std::complex<double>(xsum.xd[0],xsum.xd[1]);
            }
            if (nb) {
                sum += *A * *B;
                ++A;
                Maybe<!c2>::increment(B);
            }
            return Maybe<c2>::conj(sum);
#else
            std::complex<double> sum = 0.;
            do {
                sum += *A * *B;
                ++A;
                Maybe<!c2>::increment(B);
            } while (--n);
            return Maybe<c2>::conj(sum);
#endif
        } else {
            return 0.;
Example #6
0
void GCAllocator::Setup(const ::CrossNetRuntime::InitOptions & options)
{
    CROSSNET_ASSERT(IsAligned(sizeof(AllocStructure)), "");
    CROSSNET_ASSERT(IsAligned((int)options.mMainBuffer), "");

    // Set the allocated buffer to a specific pattern (to detect bugs earlier)
    __memset__(options.mMainBuffer, 0xA5, options.mMainBufferSize);

    sCurrentAllocPointer = static_cast<unsigned char *>(options.mMainBuffer);
    sEndMainBuffer = sCurrentAllocPointer + options.mMainBufferSize;

    ClearBins();
}
Example #7
0
Status UnalignedWriter::Append(const u8* data, size_t size) const
{
	while(size != 0)
	{
		// optimization: write directly from the input buffer, if possible
		const size_t alignedSize = (size / BLOCK_SIZE) * BLOCK_SIZE;
		if(m_bytesUsed == 0 && IsAligned(data, maxSectorSize) && alignedSize != 0)
		{
			io::Operation op(*m_file.get(), (void*)data, alignedSize, m_alignedOfs);
			RETURN_STATUS_IF_ERR(io::Run(op));
			m_alignedOfs += (off_t)alignedSize;
			data += alignedSize;
			size -= alignedSize;
		}

		const size_t chunkSize = std::min(size, BLOCK_SIZE-m_bytesUsed);
		memcpy(m_alignedBuf.get()+m_bytesUsed, data, chunkSize);
		m_bytesUsed += chunkSize;
		data += chunkSize;
		size -= chunkSize;

		if(m_bytesUsed == BLOCK_SIZE)
			RETURN_STATUS_IF_ERR(WriteBlock());
	}

	return INFO::OK;
}
Example #8
0
void page_aligned_free(void* p, size_t size)
{
	if(!p)
		return;
	ENSURE(IsAligned(p, pageSize));
	const size_t alignedSize = Align<pageSize>(size);
	(void)mem_Release((u8*)p, alignedSize);
}
Example #9
0
// As you can see, we can free a single block of memory at any time without being inside a GC
void GCAllocator::Free(void * ptr, int size)
{
    CROSSNET_ASSERT(IsAligned(ptr), "");

    AllocStructure * freedPtr = static_cast<AllocStructure *>(ptr);
    int alignedSize = Align(size);
    InternalFree(freedPtr, alignedSize);
}
Example #10
0
  // Allocates a chunk.
  void *allocate(uptr Size, uptr Alignment, AllocType Type) {
    if (UNLIKELY(!ThreadInited))
      initThread();
    if (!IsPowerOfTwo(Alignment)) {
      dieWithMessage("ERROR: malloc alignment is not a power of 2\n");
    }
    if (Alignment > MaxAlignment)
      return BackendAllocator.ReturnNullOrDie();
    if (Alignment < MinAlignment)
      Alignment = MinAlignment;
    if (Size == 0)
      Size = 1;
    if (Size >= MaxAllowedMallocSize)
      return BackendAllocator.ReturnNullOrDie();
    uptr RoundedSize = RoundUpTo(Size, MinAlignment);
    uptr ExtraBytes = ChunkHeaderSize;
    if (Alignment > MinAlignment)
      ExtraBytes += Alignment;
    uptr NeededSize = RoundedSize + ExtraBytes;
    if (NeededSize >= MaxAllowedMallocSize)
      return BackendAllocator.ReturnNullOrDie();

    void *Ptr;
    if (LIKELY(!ThreadTornDown)) {
      Ptr = BackendAllocator.Allocate(&Cache, NeededSize, MinAlignment);
    } else {
      SpinMutexLock l(&FallbackMutex);
      Ptr = BackendAllocator.Allocate(&FallbackAllocatorCache, NeededSize,
                               MinAlignment);
    }
    if (!Ptr)
      return BackendAllocator.ReturnNullOrDie();

    // If requested, we will zero out the entire contents of the returned chunk.
    if (ZeroContents && BackendAllocator.FromPrimary(Ptr))
       memset(Ptr, 0, BackendAllocator.GetActuallyAllocatedSize(Ptr));

    uptr AllocBeg = reinterpret_cast<uptr>(Ptr);
    uptr ChunkBeg = AllocBeg + ChunkHeaderSize;
    if (!IsAligned(ChunkBeg, Alignment))
      ChunkBeg = RoundUpTo(ChunkBeg, Alignment);
    CHECK_LE(ChunkBeg + Size, AllocBeg + NeededSize);
    ScudoChunk *Chunk =
        reinterpret_cast<ScudoChunk *>(ChunkBeg - ChunkHeaderSize);
    UnpackedHeader Header = {};
    Header.State = ChunkAllocated;
    Header.Offset = (ChunkBeg - ChunkHeaderSize - AllocBeg) >> MinAlignmentLog;
    Header.AllocType = Type;
    Header.RequestedSize = Size;
    Header.Salt = static_cast<u16>(Prng.Next());
    Chunk->storeHeader(&Header);
    void *UserPtr = reinterpret_cast<void *>(ChunkBeg);
    // TODO(kostyak): hooks sound like a terrible idea security wise but might
    //                be needed for things to work properly?
    // if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(UserPtr, Size);
    return UserPtr;
  }
// add a request to the queue.
HRESULT
  CAsyncIo::Request(
  LONGLONG llPos,
  LONG lLength,
  BOOL bAligned,
  BYTE * pBuffer,
  LPVOID pContext,
  DWORD_PTR dwUser)
{
  if(bAligned)
  {
    if(!IsAligned(llPos) ||
      !IsAligned(lLength) ||
      !IsAligned((LONG_PTR) pBuffer))
    {
      return VFW_E_BADALIGN;
    }
  }

  CAsyncRequest* pRequest = new CAsyncRequest;
  if (!pRequest)
    return E_OUTOFMEMORY;

  HRESULT hr = pRequest->Request(this,
    m_pStream,
    llPos,
    lLength,
    bAligned,
    pBuffer,
    pContext,
    dwUser);
  if(SUCCEEDED(hr))
  {
    // might fail if flushing
    hr = PutWorkItem(pRequest);
  }

  if(FAILED(hr))
  {
    delete pRequest;
  }

  return hr;
}
	size_t StreamProcessor::ProcessPacketWithPayload(StreamProcessor &p, DataVector::iterator curr, DataVector::iterator bufferEnd)
	{
		OVR_CAPTURE_STATIC_ASSERT(PacketType::s_hasPayload == true);

		PacketType                           packet      = {0};
		typename PacketType::PayloadSizeType payloadSize = 0;

		// Check to see if we have enough room for the packet...
		if(sizeof(packet) > (size_t)std::distance(curr, bufferEnd))
			return 0;

		// Load the packet...
		memcpy(&packet, &*curr, sizeof(packet));
		curr += sizeof(packet);

		// Check to see if we have enough room for the payload header...
		if(sizeof(payloadSize) > (size_t)std::distance(curr, bufferEnd))
			return 0;

		// Load the payload header...
		memcpy(&payloadSize, &*curr, sizeof(payloadSize));
		curr += sizeof(payloadSize);

		// Check to see if we have enough room for the payload...
		if(((DataVector::difference_type)payloadSize) > std::distance(curr, bufferEnd))
			return 0;

		void *payloadUnaligned = &*curr;
		void *payloadAligned   = NULL;
		if(payloadSize > 0)
		{
			if(IsAligned(payloadUnaligned, PacketType::s_payloadAlignment))
			{
				// avoid re-allocation+copy unless necessary...
				payloadAligned = payloadUnaligned;
			}
			else
			{
				// TODO: reusable scratch memory blob...
				payloadAligned = malloc(payloadSize);
				memcpy(payloadAligned, payloadUnaligned, payloadSize);
			}
		}

		// Dispatch to callback...
		p.DispatchPacket(packet, payloadAligned, (size_t)payloadSize);

		if(payloadAligned && payloadAligned != payloadUnaligned)
		{
			free(payloadAligned);
		}

		// Return the total size of the packet, including the header...
		return sizeof(PacketHeader) + sizeof(packet) + sizeof(payloadSize) + payloadSize;
	}
// perform a synchronous read request on this thread.
// Need to hold m_csFile while doing this (done in request object)
HRESULT
  CAsyncIo::SyncReadAligned(
  LONGLONG llPos,
  LONG lLength,
  BYTE * pBuffer,
  LONG * pcbActual,
  PVOID pvContext)
{
  CheckPointer(pcbActual,E_POINTER);

  if(!IsAligned(llPos) ||
    !IsAligned(lLength) ||
    !IsAligned((LONG_PTR) pBuffer))
  {
    return VFW_E_BADALIGN;
  }

  CAsyncRequest request;

  m_pStream->Lock();

  HRESULT hr = request.Request(this,
    m_pStream,
    llPos,
    lLength,
    TRUE,
    pBuffer,
    pvContext,
    0);
  if(SUCCEEDED(hr))
  {
    hr = request.Complete();
  }

  m_pStream->Unlock();

  // return actual data length
  *pcbActual = request.GetActualLength();
  return hr;
}
Example #14
0
/*
 * Test if it is safe to issue a unsynced change to dst/size using a
 * writesize write.  Outputs the offset to start the write at.
 * 1 if it is ok, 0 if it is not ok.
 */
static int IsTrustedWrite(uint8_t *dst,
                          int size,
                          int writesize,
                          intptr_t* offset) {
    if (size > writesize) {
        return 0;
    }
    if (!IsAligned(dst, size, kInstructionFetchSize)) {
        return 0;
    }
    if (writesize <= kTrustAligned && IsAligned(dst, size, writesize)) {
        /* aligned write is trusted */
        *offset = (intptr_t) dst & (writesize - 1);
        return 1;
    }
    if (writesize <= kTrustUnaligned) {
        /* unaligned write is trusted */
        *offset = 0;
        return 1;
    }
    return 0;
}
Example #15
0
 // Deallocates a Chunk, which means adding it to the delayed free list (or
 // Quarantine).
 void deallocate(void *UserPtr, uptr DeleteSize, AllocType Type) {
   if (UNLIKELY(!ThreadInited))
     initThread();
   // TODO(kostyak): see hook comment above
   // if (&__sanitizer_free_hook) __sanitizer_free_hook(UserPtr);
   if (!UserPtr)
     return;
   uptr ChunkBeg = reinterpret_cast<uptr>(UserPtr);
   if (!IsAligned(ChunkBeg, MinAlignment)) {
     dieWithMessage("ERROR: attempted to deallocate a chunk not properly "
                    "aligned at address %p\n", UserPtr);
   }
   ScudoChunk *Chunk =
       reinterpret_cast<ScudoChunk *>(ChunkBeg - ChunkHeaderSize);
   UnpackedHeader OldHeader;
   Chunk->loadHeader(&OldHeader);
   if (OldHeader.State != ChunkAllocated) {
     dieWithMessage("ERROR: invalid chunk state when deallocating address "
                    "%p\n", Chunk);
   }
   UnpackedHeader NewHeader = OldHeader;
   NewHeader.State = ChunkQuarantine;
   Chunk->compareExchangeHeader(&NewHeader, &OldHeader);
   if (DeallocationTypeMismatch) {
     // The deallocation type has to match the allocation one.
     if (NewHeader.AllocType != Type) {
       // With the exception of memalign'd Chunks, that can be still be free'd.
       if (NewHeader.AllocType != FromMemalign || Type != FromMalloc) {
         dieWithMessage("ERROR: allocation type mismatch on address %p\n",
                        Chunk);
       }
     }
   }
   uptr Size = NewHeader.RequestedSize;
   if (DeleteSizeMismatch) {
     if (DeleteSize && DeleteSize != Size) {
       dieWithMessage("ERROR: invalid sized delete on chunk at address %p\n",
                      Chunk);
     }
   }
   if (LIKELY(!ThreadTornDown)) {
     AllocatorQuarantine.Put(&ThreadQuarantineCache,
                             QuarantineCallback(&Cache), Chunk, Size);
   } else {
     SpinMutexLock l(&FallbackMutex);
     AllocatorQuarantine.Put(&FallbackQuarantineCache,
                             QuarantineCallback(&FallbackAllocatorCache),
                             Chunk, Size);
   }
 }
Example #16
0
HRESULT
CAsyncIo::SyncReadAligned(
            LONGLONG llPos,
            LONG lLength,
            BYTE* pBuffer,
            LONG* pcbActual,
            PVOID pvContext
            )
{
    if (!IsAligned(llPos) ||
	!IsAligned(lLength) ||
	!IsAligned((LONG) pBuffer)) {
            return VFW_E_BADALIGN;
    }

    CAsyncRequest request;

    HRESULT hr = request.Request(
                    this,
                    m_pStream,
                    llPos,
                    lLength,
                    TRUE,
                    pBuffer,
                    pvContext,
                    0);

    if (FAILED(hr)) {
        return hr;
    }

    hr = request.Complete();

    
    *pcbActual = request.GetActualLength();
    return hr;
}
int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
                        StackTrace *stack) {
  if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
    if (AllocatorMayReturnNull())
      return errno_EINVAL;
    ReportInvalidPosixMemalignAlignment(alignment, stack);
  }
  void *ptr = HwasanAllocate(stack, size, alignment, false);
  if (UNLIKELY(!ptr))
    // OOM error is already taken care of by HwasanAllocate.
    return errno_ENOMEM;
  CHECK(IsAligned((uptr)ptr, alignment));
  *memptr = ptr;
  return 0;
}
Example #18
0
void CControl::FilterLineAngle(vector<Point2f> n_inlinevct,
			       vector<Point2f>& n_outlinevct,float n_angle,
			       float n_threshold)
{
  for(int i=0;i<n_inlinevct.size();i++)
    {
      //get points
      Point2f n_pt1=n_inlinevct.at(i++);
      Point2f n_pt2=n_inlinevct.at(i);
      //cal angle
      float n_dy=n_pt1.y-n_pt2.y;
      float n_dx=n_pt1.x-n_pt2.x;
      float n_angleline=fastAtan2(n_dy,n_dx);
      if(IsAligned(n_angle,n_angleline,n_threshold))
	{
	  //add to out linevct
	  n_outlinevct.push_back(n_pt1);
	  n_outlinevct.push_back(n_pt2);
	}
    }
}
Example #19
0
static Status validate_da(DynArray* da)
{
	if(!da)
		WARN_RETURN(ERR::INVALID_POINTER);
//	u8* const base           = da->base;
	const size_t max_size_pa = da->max_size_pa;
	const size_t cur_size    = da->cur_size;
	const size_t pos         = da->pos;

	// note: this happens if max_size == 0
//	if(debug_IsPointerBogus(base))
//		WARN_RETURN(ERR::_1);
	// note: don't check if base is page-aligned -
	// might not be true for 'wrapped' mem regions.
	if(!IsAligned(max_size_pa, pageSize))
		WARN_RETURN(ERR::_3);
	if(cur_size > max_size_pa)
		WARN_RETURN(ERR::_4);
	if(pos > cur_size || pos > max_size_pa)
		WARN_RETURN(ERR::_5);

	return INFO::OK;
}
Example #20
0
 static INLINE bool isAligned(const void *Ptr) {
   return IsAligned(reinterpret_cast<uptr>(Ptr), MinAlignment);
 }
Example #21
0
  uint8_t * m_cur;

  DISALLOW_COPY_AND_MOVE(ReverseMapVisitor);
};

template <typename TWriter>
class FreezeVisitor
{
public:
  explicit FreezeVisitor(TWriter & writer) : m_writer(writer), m_bytesWritten(0) {}

  template <typename T>
  typename enable_if<!is_pod<T>::value, FreezeVisitor &>::type operator()(T & val,
                                                                          char const * /* name */)
  {
    ASSERT(IsAligned(m_writer.Pos()), ());
    val.map(*this);
    return *this;
  }

  template <typename T>
  typename enable_if<is_pod<T>::value, FreezeVisitor &>::type operator()(T & val,
                                                                         char const * /* name */)
  {
    ASSERT(IsAligned(m_writer.Pos()), ());
    m_writer.Write(&val, sizeof(T));
    m_bytesWritten += sizeof(T);
    WritePadding(m_writer, m_bytesWritten);
    return *this;
  }
Example #22
0
void * GCAllocator::Allocate(int size, bool afterGC)
{
    AllocStructure *  ptr;

    // Old obsolete comments:

    // Either the small object allocator on the corresponding is empty
    // or we are allocating a bigger size
    // For this implementation, we are not differentiating between medium and bigger size...
    // I.e. 2Kb / 16 Kb / 100 Kb will be allocated on the same buffer
    // We might certainly want to improve this later...

    // Here it means that we reached the end of the buffer
    //  First look at the free block that are sparkled in the buffer
    // Start by the closest size and continue until the biggest
    // We use the next power of 2 to make sure the next block is big enough
    // In reality we should try to have a best fit (that one is in between first fit / best fit)
    // Or at least a better fit ;)


    if (size <= SMALL_SIZE_BIN)
    {
        // Allocation that happens most of the time
        // First look at the small object allocator
        // We need to assume that the small object allocator is filled enough

        // By doing this we reuse memory that has been allocated and freed before
        // This reduces memory consumption and fragmentation as well

/*
        int indexSmallBin = size >> ALIGNMENT_SHIFT;
        ptr = sSmallBin[indexSmallBin];
        if (ptr != NULL)
        {
            sSmallBin[indexSmallBin] = ptr->mNext;
            // Done!
            // Cost:    2 tests, 1 operation, 2 reads, 1 write
            return (ptr);
        }
*/

        int alignedSize = Align(size);

        // Special optimization for small size
        ptr = sCurrentMediumPointer;
        if (ptr != NULL)
        {
            CROSSNET_ASSERT(IsAligned(ptr), "");
            CROSSNET_ASSERT(IsAligned(sCurrentMediumSize), "");

            // Good news, there is already a cached medium size
//          if (sCurrentMediumSize >= size)     // For whatever reason, this is actually crashing... Use the bigger size,
                                                //  this should not change tremendously the performance...
                                                //  TODO:   Investigate this...
            if (sCurrentMediumSize >= SMALL_SIZE_BIN)
            {
                CROSSNET_ASSERT(sCurrentMediumSize >= alignedSize, "");
                // And the buffer is big enough...
                // ptr is going to be the allocated pointer

                // Note that when we use the medium buffer cache, we are not reading / writing anything more
                // I.e. we are not pushing free blocks all over the place, nor poping / pushing in the medium size bin
                // Or even looking iteratively at each medium size bins
                sCurrentMediumPointer = (AllocStructure *)(((unsigned char *)ptr) + alignedSize);
                sCurrentMediumSize -= alignedSize;

                return (ptr);
            }

            // The buffer cannot be used anymore (smaller than the asked size)
            // It certainly is a small size buffer now too ;)

            // Clear the cache and look at the next medium buffer...
            ReconcileMediumCache();
        }

{
    unsigned char * currentAlloc = sCurrentAllocPointer;
    unsigned char * endAlloc = currentAlloc + alignedSize;

    if (endAlloc < sEndMainBuffer)
    {
        // We have enough memory to allocate
        sCurrentAllocPointer = endAlloc;

        // Second most common case (if we are not running out of memory quickly)
        //  Cost if size > SMALL_SIZE_BIN:  2 tests, 2 operations, 1 read, 1 write
        //
        //  Cost if size <= SMALL_SIZE_BIN: 3 tests, 3 operations, 2 reads, 1 write
        return (currentAlloc);
    }
}

        // A bit more optimized for small size...
        int topBit = SMALL_SIZE_SHIFT;
        do
        {
            ptr = sMediumBin[topBit];
            if (ptr != NULL)
            {
                // We found a block that should have enough size...
                break;
            }
            ++topBit;
        }
        while (topBit < 32);

        if (ptr != NULL)
        {
            CROSSNET_ASSERT(ptr->mSize >= size, "");

            // Good, we found a free block of the good size!
            // Remove it from the free list, move the next free block at the top
            sMediumBin[topBit] = ptr->mNext;

            int deltaSize = ptr->mSize - alignedSize;
            CROSSNET_ASSERT(deltaSize >= 0, "");                // The free block should be at least as big as the allocation we are looking for
            CROSSNET_ASSERT(ptr->mSize >= (1 << topBit), "");   // The block should be bigger than the corresponding top bit
            CROSSNET_ASSERT(IsAligned(deltaSize), "");

            // Because we are allocating for a small size and we look inside the medium bin
            // We know that we are going to have left over room...
            // This will increase memory fragmentation

            AllocStructure * newFreeBlock = (AllocStructure *)(((unsigned char *)ptr) + alignedSize);

            // Put this medium buffer in the cache for next time...
            sCurrentMediumPointer = newFreeBlock;
            sCurrentMediumSize = deltaSize;

            // No need to free the block...
            return (ptr);
        }
    }
    else
    {
        // Bigger than small size bin
        int alignedSize = Align(size);

{

    unsigned char * currentAlloc = sCurrentAllocPointer;
    unsigned char * endAlloc = currentAlloc + alignedSize;

    if (endAlloc < sEndMainBuffer)
    {
        // We have enough memory to allocate
        sCurrentAllocPointer = endAlloc;

        // Second most common case (if we are not running out of memory quickly)
        //  Cost if size > SMALL_SIZE_BIN:  2 tests, 2 operations, 1 read, 1 write
        //
        //  Cost if size <= SMALL_SIZE_BIN: 3 tests, 3 operations, 2 reads, 1 write
        return (currentAlloc);
    }
}

        // In that case we have to update the medium bin with the cached medium pointer (if there is one)
        SafeReconcileMediumCache();

        int topBit = TopBit(NextPowerOf2(size));
        do
        {
            ptr = sMediumBin[topBit];
            if (ptr != NULL)
            {
                // We found a block that should have enough size...
                break;
            }
            ++topBit;
        }
        while (topBit < 32);

        if (ptr != NULL)
        {
            CROSSNET_ASSERT(ptr->mSize >= size, "");

            // Good, we found a free block of the good size!
            // Remove it from the free list, move the next free block at the top
            sMediumBin[topBit] = ptr->mNext;

            int deltaSize = ptr->mSize - alignedSize;
            CROSSNET_ASSERT(deltaSize >= 0, "");                // The free block should be at least as big as the allocation we are looking for
            CROSSNET_ASSERT(ptr->mSize >= (1 << topBit), "");   // The block should be bigger than the corresponding top bit
            CROSSNET_ASSERT(IsAligned(deltaSize), "");

            if (deltaSize > 0)
            {
                // It means that there is some left over from the block
                // We either have to push it on the small bin or on the medium bin
                // This will increase memory fragmentation

                AllocStructure * newFreeBlock = (AllocStructure *)(((unsigned char *)ptr) + alignedSize);
                InternalFree(newFreeBlock, deltaSize);
            }
            return (ptr);
        }
    }
/*
    {
        unsigned char * currentAlloc = sCurrentAllocPointer;
        unsigned char * endAlloc = currentAlloc + alignedSize;

        if (endAlloc < sEndMainBuffer)
        {
            // We have enough memory to allocate
            sCurrentAllocPointer = endAlloc;

            // Second most common case (if we are not running out of memory quickly)
            //  Cost if size > SMALL_SIZE_BIN:  2 tests, 2 operations, 1 read, 1 write
            //
            //  Cost if size <= SMALL_SIZE_BIN: 3 tests, 3 operations, 2 reads, 1 write
            return (currentAlloc);
        }
    }
*/

    // Let's recapitulate, we did not find a free block in:
    //  1. The Small Object Allocator (recycled small objects)
    //  2. At the end of the main buffer (for new objects)
    //  3. In the medium allocator (recycled medium and big objects).

    if (afterGC)
    {
        // We did a GC already with no luck...
        // let's try with the last user allocator
        AllocateFunctionPointer func = ::CrossNetRuntime::GetOptions().mAllocateAfterGCCallback;
        if (func != NULL)
        {
            return (func(size));
        }
        // No function pointer set, can't allocate
        return (NULL);
    }
    else
    {
        // Before we collect, ask the user what he wants to do
        AllocateFunctionPointer func = ::CrossNetRuntime::GetOptions().mAllocateBeforeGCCallback;
        if (func != NULL)
        {
            // He provided a callback, let's use it
            void * result = func(size);
            if (result != NULL)
            {
                // And the callback allocated something!
                return (result);
            }
        }
    }

    CROSSNET_ASSERT(afterGC == false, "Can only before collect here!");

    // So we are before collect and everything failed,
    //  Even the user didn't provide an allocation or were not able to allocate more

    // The only remaining thing to do is to Garbage Collect,
    // hoping it will free some memory...

    GCManager::Collect(GCManager::MAX_GENERATION, false);

    // Recurse the same function again, this time stating that the GC has been done already
    // This won't be done more often...
    return (Allocate(size, true));
}
Example #23
0
STDMETHODIMP CRFSOutputPin::RequestAllocator (IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual)
{
    if (!(pPreferred && pProps && ppActual))
        return E_POINTER;

    ALLOCATOR_PROPERTIES actual;
    HRESULT hr;

    DbgLog((LOG_TRACE, 2, L"Requested alignment = %ld", pProps->cbAlign));
    if (pProps->cbAlign)
        m_align = pProps->cbAlign;
    else
        pProps->cbAlign = m_align;

    if (pPreferred)
    {
        hr = pPreferred->SetProperties (pProps, &actual);

        if (SUCCEEDED (hr) && IsAligned (actual.cbAlign))
        {
            DbgLog((LOG_TRACE, 2, L"Using preferred allocator."));
            pPreferred->AddRef ();
            *ppActual = pPreferred;
            return S_OK;
        }
    }

    CMemAllocator *pMemObject = new CMemAllocator (L"RFS memory allocator", NULL, &hr);

    if (!pMemObject)
        return E_OUTOFMEMORY;

    if (FAILED (hr))
    {
        delete pMemObject;
        return hr;
    }

    IMemAllocator* pAlloc;

    hr = pMemObject->QueryInterface (IID_IMemAllocator, (void **) &pAlloc);

    if (FAILED (hr))
    {
        delete pMemObject;
        return E_NOINTERFACE;
    }

    hr = pAlloc->SetProperties (pProps, &actual);

    if (SUCCEEDED (hr) && IsAligned (actual.cbAlign))
    {
        DbgLog((LOG_TRACE, 2, L"Using our allocator."));
        *ppActual = pAlloc;
        return S_OK;
    }

    pAlloc->Release ();

    if (SUCCEEDED (hr))
        hr = VFW_E_BADALIGN;

    DbgLog((LOG_TRACE, 2, L"RequestAllocator failed."));
    return hr;
}
Example #24
0
STDMETHODIMP CRFSOutputPin::Request (IMediaSample* pSample, DWORD_PTR dwUser)
{
    LONGLONG llPosition;
    DWORD lLength;
    BYTE* pBuffer;

    if (m_flush)
    {
        DbgLog((LOG_TRACE, 2, L"Request called during flush."));
        return VFW_E_WRONG_STATE;
    }

    if (!m_file)
    {
        DbgLog((LOG_TRACE, 2, L"Request called with no file loaded."));
        return E_UNEXPECTED;
    }

    HRESULT hr = ConvertSample (pSample, &llPosition, &lLength, &pBuffer);

    if (FAILED (hr))
        return hr;

    if (!(IsAligned ((INT_PTR) llPosition) && IsAligned ((INT_PTR) lLength) && IsAligned ((INT_PTR) pBuffer)))
    {
        DbgLog((LOG_TRACE, 2, L"SyncReadAligned bad alignment. align = %lu, pos = %lld, len = %lu, buf = %p",
                m_align, llPosition, lLength, pBuffer));
        return VFW_E_BADALIGN;
    }

    LARGE_INTEGER offset;
    DWORD to_read, acc = 0;
    LONGLONG offset2;
    int pos = m_file->FindStartPart (llPosition);

    if (pos == -1)
        return S_FALSE;

    ReadRequest *request = new ReadRequest ();

    if (!request)
        return E_OUTOFMEMORY;

    Anchor<ReadRequest> arr (&request);

    request->dwUser = dwUser;
    request->pSample = pSample;
    request->count = 0;

    CRFSFilePart *part = m_file->array + pos;

    offset2 = llPosition - part->in_file_offset;
    offset.QuadPart = part->in_rar_offset + offset2;

    while (true)
    {
        SubRequest *sr = new SubRequest ();

        if (!sr)
        {
            ErrorMsg (0, L"Out of memory.");
            return E_OUTOFMEMORY;
        }

        request->subreqs.InsertLast (sr);
        request->count ++;

        to_read = min (lLength, (DWORD) (part->size - offset2));

        sr->file = part->file;
        sr->expected = to_read;
        sr->o.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);

        if (!sr->o.hEvent)
        {
            sr->o.hEvent = INVALID_HANDLE_VALUE;
            return S_FALSE;
        }

        sr->o.Offset = offset.LowPart;
        sr->o.OffsetHigh = offset.HighPart;

        if (!ReadFile (part->file, pBuffer + acc, to_read, NULL, &sr->o))
        {
            DWORD err = GetLastError ();

            // FIXME: Do something smart in response to EOF.
            if (err != ERROR_IO_PENDING && err != ERROR_HANDLE_EOF)
            {
                ErrorMsg (err, L"CRFSOutputPin::Request - ReadFile");
                return S_FALSE;
            }
        }
        lLength -= to_read;
        acc += to_read;

        if (lLength <= 0)
            break;

        pos ++;

        if (pos >= m_file->parts)
            return S_FALSE;

        part ++;
        offset2 = 0;
        offset.QuadPart = part->in_rar_offset;
    }

    m_lock.Lock ();

    arr.Release ();
    m_requests.InsertFirst (request);

    if (!SetEvent (m_event))
        ErrorMsg (GetLastError (), L"CRFSOutputPin::Request - SetEvent");

    m_lock.Unlock ();

    return S_OK;
}
Example #25
0
bool jl::ObjectPool::IsBoundedAndAligned( const void* pObject, const unsigned char* pObjectBuffer, unsigned nCapacity, unsigned nStride )
{
    return IsBounded( pObject, pObjectBuffer, nCapacity, nStride )
        && IsAligned( pObject, pObjectBuffer, nStride );
}
 // find out if a residue is aligned, by Sequence - only works for non-repeated Sequences!
 bool IsAligned(const Sequence *sequence, unsigned int seqIndex) const
 {
     int row = GetRowForSequence(sequence);
     if (row < 0) return false;
     return IsAligned(row, seqIndex);
 }
Example #27
0
 /// Check if there's a gap on the selected row.
 inline bool IsGap(void) const {
     return !IsAligned()  &&  GetRange().Empty();
 }