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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
|
@ -27,7 +27,8 @@
|
||||||
PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name,
|
PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name,
|
||||||
size_t minSize, size_t maxSize, uint32 minCountPerBlock)
|
size_t minSize, size_t maxSize, uint32 minCountPerBlock)
|
||||||
: fOverhead(0),
|
: fOverhead(0),
|
||||||
fStatus(B_NO_INIT)
|
fStatus(B_NO_INIT),
|
||||||
|
fMemoryWaitersCount(0)
|
||||||
{
|
{
|
||||||
fName = strdup(name);
|
fName = strdup(name);
|
||||||
mutex_init_etc(&fLock, fName, MUTEX_FLAG_CLONE_NAME);
|
mutex_init_etc(&fLock, fName, MUTEX_FLAG_CLONE_NAME);
|
||||||
|
@ -90,6 +91,8 @@ PhysicalMemoryAllocator::PhysicalMemoryAllocator(const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
fPhysicalBase = physicalEntry.address;
|
fPhysicalBase = physicalEntry.address;
|
||||||
|
|
||||||
|
fNoMemoryCondition.Init(this, "USB PMA");
|
||||||
fStatus = B_OK;
|
fStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,11 +167,10 @@ PhysicalMemoryAllocator::Allocate(size_t size, void **logicalAddress,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 retries = 5000;
|
|
||||||
while (retries-- > 0) {
|
|
||||||
if (!_Lock())
|
if (!_Lock())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
TRACE(("PMA: will use array %ld (blocksize: %ld) to allocate %ld bytes\n", arrayToUse, fBlockSize[arrayToUse], size));
|
TRACE(("PMA: will use array %ld (blocksize: %ld) to allocate %ld bytes\n", arrayToUse, fBlockSize[arrayToUse], size));
|
||||||
uint8 *targetArray = fArray[arrayToUse];
|
uint8 *targetArray = fArray[arrayToUse];
|
||||||
uint32 arrayOffset = fArrayOffset[arrayToUse] % arrayLength;
|
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();
|
_Unlock();
|
||||||
|
|
||||||
TRACE_ERROR(("PMA: found no free slot to store %ld bytes (%ld tries left)\n", size, retries));
|
TRACE_ERROR(("PMA: found no free slot to store %ld bytes, waiting\n",
|
||||||
// we provide a scratch space here, memory will probably be freed
|
size));
|
||||||
// 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.
|
entry.Wait();
|
||||||
snooze(100);
|
|
||||||
|
if (!_Lock())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fMemoryWaitersCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
@ -292,6 +303,9 @@ PhysicalMemoryAllocator::Deallocate(size_t size, void *logicalAddress,
|
||||||
arrayIndex >>= 1;
|
arrayIndex >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fMemoryWaitersCount > 0)
|
||||||
|
fNoMemoryCondition.NotifyAll();
|
||||||
|
|
||||||
_Unlock();
|
_Unlock();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef _PHYSICAL_MEMORY_ALLOCATOR_H_
|
#ifndef _PHYSICAL_MEMORY_ALLOCATOR_H_
|
||||||
#define _PHYSICAL_MEMORY_ALLOCATOR_H_
|
#define _PHYSICAL_MEMORY_ALLOCATOR_H_
|
||||||
|
|
||||||
|
#include <condition_variable.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
||||||
|
@ -58,6 +59,9 @@ private:
|
||||||
size_t *fArrayOffset;
|
size_t *fArrayOffset;
|
||||||
uint8 **fArray;
|
uint8 **fArray;
|
||||||
|
|
||||||
|
ConditionVariable fNoMemoryCondition;
|
||||||
|
uint32 fMemoryWaitersCount;
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
uint32 fDebugBase;
|
uint32 fDebugBase;
|
||||||
uint32 fDebugChunkSize;
|
uint32 fDebugChunkSize;
|
||||||
|
|
Loading…
Reference in New Issue