An IORequest's memory needs to be unlocked when it is done. Since this
happens in the I/O scheduler thread, we need to use unlock_memory_etc().
Changed the IOBuffer::{Lock,Unlock}Memory() methods accordingly.
The test driver seems to be working stable, now.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26609 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -108,7 +108,8 @@ IOScheduler::ScheduleRequest(IORequest* request)
|
||||
// lock memory (via another thread or a dedicated call).
|
||||
|
||||
if (buffer->IsVirtual()) {
|
||||
status_t status = buffer->LockMemory(request->IsWrite());
|
||||
status_t status = buffer->LockMemory(B_CURRENT_TEAM,
|
||||
request->IsWrite());
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -76,13 +76,13 @@ IOBuffer::SetVecs(const iovec* vecs, uint32 count, size_t length, uint32 flags)
|
||||
|
||||
|
||||
status_t
|
||||
IOBuffer::LockMemory(bool isWrite)
|
||||
IOBuffer::LockMemory(team_id team, bool isWrite)
|
||||
{
|
||||
for (uint32 i = 0; i < fVecCount; i++) {
|
||||
status_t status = lock_memory(fVecs[i].iov_base, fVecs[i].iov_len,
|
||||
isWrite ? 0 : B_READ_DEVICE);
|
||||
status_t status = lock_memory_etc(team, fVecs[i].iov_base,
|
||||
fVecs[i].iov_len, isWrite ? 0 : B_READ_DEVICE);
|
||||
if (status != B_OK) {
|
||||
_UnlockMemory(i, isWrite);
|
||||
_UnlockMemory(team, i, isWrite);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -92,19 +92,19 @@ IOBuffer::LockMemory(bool isWrite)
|
||||
|
||||
|
||||
void
|
||||
IOBuffer::_UnlockMemory(size_t count, bool isWrite)
|
||||
IOBuffer::_UnlockMemory(team_id team, size_t count, bool isWrite)
|
||||
{
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
unlock_memory(fVecs[i].iov_base, fVecs[i].iov_len,
|
||||
unlock_memory_etc(team, fVecs[i].iov_base, fVecs[i].iov_len,
|
||||
isWrite ? 0 : B_READ_DEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IOBuffer::UnlockMemory(bool isWrite)
|
||||
IOBuffer::UnlockMemory(team_id team, bool isWrite)
|
||||
{
|
||||
_UnlockMemory(fVecCount, isWrite);
|
||||
_UnlockMemory(team, fVecCount, isWrite);
|
||||
}
|
||||
|
||||
|
||||
@@ -595,6 +595,12 @@ IORequest::ChunkFinished(IORequestChunk* chunk, status_t status, bool remove)
|
||||
if (fStatus == 1)
|
||||
fStatus = B_OK;
|
||||
|
||||
// unlock the memory
|
||||
// TODO: That should only happen for the request that locked the memory,
|
||||
// not for its ancestors.
|
||||
if (fBuffer->IsVirtual())
|
||||
fBuffer->UnlockMemory(fTeam, fIsWrite);
|
||||
|
||||
// Cache the callbacks before we unblock waiters and unlock. Any of the
|
||||
// following could delete this request, so we don't want to touch it once
|
||||
// we have started telling others that it is done.
|
||||
|
||||
@@ -49,13 +49,14 @@ public:
|
||||
size_t VecCount() const { return fVecCount; }
|
||||
size_t Capacity() const { return fCapacity; }
|
||||
|
||||
status_t LockMemory(bool isWrite);
|
||||
void UnlockMemory(bool isWrite);
|
||||
status_t LockMemory(team_id team, bool isWrite);
|
||||
void UnlockMemory(team_id team, bool isWrite);
|
||||
|
||||
private:
|
||||
~IOBuffer();
|
||||
// not implemented
|
||||
void _UnlockMemory(size_t count, bool isWrite);
|
||||
void _UnlockMemory(team_id team, size_t count,
|
||||
bool isWrite);
|
||||
|
||||
bool fUser;
|
||||
bool fPhysical;
|
||||
|
||||
Reference in New Issue
Block a user