Make the USB physical memory allocator more robust. Wait for space to become
available when there is none instead of spinning around. Might help with #8053 and #8058, though it's possible that leaks or interrupt issues are the cause for these. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43125 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b0ee1941f3
commit
b9a6b7844d
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2008, Haiku Inc. All rights reserved.
|
||||
* Copyright 2006-2011, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -27,7 +27,8 @@
|
||||
PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name,
|
||||
size_t minSize, size_t maxSize, uint32 minCountPerBlock)
|
||||
: fOverhead(0),
|
||||
fStatus(B_NO_INIT)
|
||||
fStatus(B_NO_INIT),
|
||||
fMemoryWaitersCount(0)
|
||||
{
|
||||
fName = strdup(name);
|
||||
mutex_init_etc(&fLock, fName, MUTEX_FLAG_CLONE_NAME);
|
||||
@ -90,6 +91,8 @@ PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name,
|
||||
}
|
||||
|
||||
fPhysicalBase = physicalEntry.address;
|
||||
|
||||
fNoMemoryCondition.Init(this, "USB PMA");
|
||||
fStatus = B_OK;
|
||||
}
|
||||
|
||||
@ -164,11 +167,10 @@ PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress,
|
||||
}
|
||||
}
|
||||
|
||||
int32 retries = 5000;
|
||||
while (retries-- > 0) {
|
||||
if (!_Lock())
|
||||
return B_ERROR;
|
||||
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;
|
||||
@ -207,14 +209,23 @@ PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress,
|
||||
}
|
||||
}
|
||||
|
||||
// no slot found
|
||||
// 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 (%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);
|
||||
TRACE_ERROR(("PMA: found no free slot to store %ld bytes, waiting\n",
|
||||
size));
|
||||
|
||||
entry.Wait();
|
||||
|
||||
if (!_Lock())
|
||||
return B_ERROR;
|
||||
|
||||
fMemoryWaitersCount--;
|
||||
}
|
||||
|
||||
return B_NO_MEMORY;
|
||||
@ -292,6 +303,9 @@ PhysicalMemoryAllocator::Deallocate(size_t size, void *logicalAddress,
|
||||
arrayIndex >>= 1;
|
||||
}
|
||||
|
||||
if (fMemoryWaitersCount > 0)
|
||||
fNoMemoryCondition.NotifyAll();
|
||||
|
||||
_Unlock();
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#ifndef _PHYSICAL_MEMORY_ALLOCATOR_H_
|
||||
#define _PHYSICAL_MEMORY_ALLOCATOR_H_
|
||||
|
||||
#include <condition_variable.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <lock.h>
|
||||
|
||||
@ -58,6 +59,9 @@ private:
|
||||
size_t *fArrayOffset;
|
||||
uint8 **fArray;
|
||||
|
||||
ConditionVariable fNoMemoryCondition;
|
||||
uint32 fMemoryWaitersCount;
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
uint32 fDebugBase;
|
||||
uint32 fDebugChunkSize;
|
||||
|
Loading…
x
Reference in New Issue
Block a user