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; } }
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(); }
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; }
// 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(); }
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.;
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(); }
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; }
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); }
// 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); }
// 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; }
/* * 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; }
// 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); } }
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; }
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); } } }
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; }
static INLINE bool isAligned(const void *Ptr) { return IsAligned(reinterpret_cast<uptr>(Ptr), MinAlignment); }
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; }
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)); }
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; }
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; }
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); }
/// Check if there's a gap on the selected row. inline bool IsGap(void) const { return !IsAligned() && GetRange().Empty(); }