void nglLock::Unlock() { // call inherited Unlock implementation (critical section or light lock) _Unlock(); // for dead-lock checker if (mRegisterToThreadChecker) { nglThread::ID threadID = nglThread::GetCurThreadID(); nglThreadChecker::Unlock(threadID, this); } }
SignalHandler::~SignalHandler() { signal_printf("%s[%d]: welcome to ~SignalHandler\n", FILE__, __LINE__); stopThreadNextIter(); if (waitingForWakeup_) { waitLock->_Lock(FILE__, __LINE__); waitLock->_Broadcast(FILE__, __LINE__); } while (isRunning()) { _Unlock(FILE__, __LINE__); dyninst_yield(); _Lock(FILE__, __LINE__); } assert(waitLock); delete waitLock; }
status_t PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress, void **physicalAddress) { // TODO: physicalAddress should be a phys_addr_t*! #ifdef HAIKU_TARGET_PLATFORM_HAIKU if (debug_debugger_running()) { for (int32 i = 0; i < 64; i++) { uint64 mask = 1LL << i; if ((fDebugUseMap & mask) == 0) { fDebugUseMap |= mask; *logicalAddress = (void *)((uint8 *)fLogicalBase + fDebugBase + i * fDebugChunkSize); *physicalAddress = (void *)(fPhysicalBase + fDebugBase + i * fDebugChunkSize); return B_OK; } } return B_NO_MEMORY; } #endif if (size == 0 || size > fBlockSize[fArrayCount - 1]) { TRACE_ERROR(("PMA: bad value for allocate (%ld bytes)\n", size)); return B_BAD_VALUE; } size_t arrayLength = 0; int32 arrayToUse = 0; for (int32 i = 0; i < fArrayCount; i++) { if (fBlockSize[i] >= size) { arrayToUse = i; arrayLength = fArrayLength[i]; break; } } int32 retries = 5000; while (retries-- > 0) { if (!_Lock()) return B_ERROR; TRACE(("PMA: will use array %ld (blocksize: %ld) to allocate %ld bytes\n", arrayToUse, fBlockSize[arrayToUse], size)); uint8 *targetArray = fArray[arrayToUse]; uint32 arrayOffset = fArrayOffset[arrayToUse] % arrayLength; for (size_t i = arrayOffset + 1; i != arrayOffset; i++) { if (i >= arrayLength) i -= arrayLength; if (targetArray[i] == 0) { // found a free slot fArrayOffset[arrayToUse] = i; // fill upwards to the smallest block uint32 fillSize = 1; uint32 arrayIndex = i; for (int32 j = arrayToUse; j >= 0; j--) { memset(&fArray[j][arrayIndex], 1, fillSize); fillSize <<= 1; arrayIndex <<= 1; } // fill downwards to the biggest block arrayIndex = i >> 1; for (int32 j = arrayToUse + 1; j < fArrayCount; j++) { fArray[j][arrayIndex]++; if (fArray[j][arrayIndex] > 1) break; arrayIndex >>= 1; } _Unlock(); size_t offset = fBlockSize[arrayToUse] * i; *logicalAddress = (void *)((uint8 *)fLogicalBase + offset); *physicalAddress = (void *)(fPhysicalBase + offset); return B_OK; } } // no slot found _Unlock(); TRACE_ERROR(("PMA: found no free slot to store %ld bytes (%ld tries left)\n", size, retries)); // we provide a scratch space here, memory will probably be freed // as soon as some other transfer is completed and cleaned up. // just wait a bit to give other threads a chance to free some slots. snooze(100); }
status_t PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress, phys_addr_t *physicalAddress) { #ifdef HAIKU_TARGET_PLATFORM_HAIKU if (debug_debugger_running()) { if (size > fDebugChunkSize) { kprintf("usb allocation of %" B_PRIuSIZE " does not fit debug chunk size %" B_PRIuSIZE "!\n", size, fDebugChunkSize); return B_NO_MEMORY; } for (size_t i = 0; i < sizeof(fDebugUseMap) * 8; i++) { uint64 mask = 1LL << i; if ((fDebugUseMap & mask) == 0) { fDebugUseMap |= mask; *logicalAddress = (void *)((uint8 *)fLogicalBase + fDebugBase + i * fDebugChunkSize); *physicalAddress = (phys_addr_t)(fPhysicalBase + fDebugBase + i * fDebugChunkSize); return B_OK; } } return B_NO_MEMORY; } #endif if (size == 0 || size > fBlockSize[fArrayCount - 1]) { TRACE_ERROR(("PMA: bad value for allocate (%ld bytes)\n", size)); return B_BAD_VALUE; } size_t arrayLength = 0; int32 arrayToUse = 0; for (int32 i = 0; i < fArrayCount; i++) { if (fBlockSize[i] >= size) { arrayToUse = i; arrayLength = fArrayLength[i]; break; } } if (!_Lock()) return B_ERROR; while (true) { TRACE(("PMA: will use array %ld (blocksize: %ld) to allocate %ld bytes\n", arrayToUse, fBlockSize[arrayToUse], size)); uint8 *targetArray = fArray[arrayToUse]; uint32 arrayOffset = fArrayOffset[arrayToUse] % arrayLength; for (size_t i = arrayOffset + 1; i != arrayOffset; i++) { if (i >= arrayLength) i -= arrayLength; if (targetArray[i] == 0) { // found a free slot fArrayOffset[arrayToUse] = i; // fill upwards to the smallest block uint32 fillSize = 1; uint32 arrayIndex = i; for (int32 j = arrayToUse; j >= 0; j--) { memset(&fArray[j][arrayIndex], 1, fillSize); fillSize <<= 1; arrayIndex <<= 1; } // fill downwards to the biggest block arrayIndex = i >> 1; for (int32 j = arrayToUse + 1; j < fArrayCount; j++) { fArray[j][arrayIndex]++; if (fArray[j][arrayIndex] > 1) break; arrayIndex >>= 1; } _Unlock(); size_t offset = fBlockSize[arrayToUse] * i; *logicalAddress = (void *)((uint8 *)fLogicalBase + offset); *physicalAddress = (phys_addr_t)(fPhysicalBase + offset); return B_OK; } } // no slot found, we need to wait ConditionVariableEntry entry; fNoMemoryCondition.Add(&entry); fMemoryWaitersCount++; _Unlock(); TRACE_ERROR(("PMA: found no free slot to store %ld bytes, waiting\n", size)); entry.Wait(); if (!_Lock()) return B_ERROR; fMemoryWaitersCount--; }
GLVertexBuffer::~GLVertexBuffer() { if(locked) _Unlock(); glDeleteBuffers(1, &glVb); }