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:
Ingo Weinhold
2008-07-24 12:29:32 +00:00
parent d4e2720651
commit 0d4d5abea1
3 changed files with 20 additions and 12 deletions
@@ -108,7 +108,8 @@ IOScheduler::ScheduleRequest(IORequest* request)
// lock memory (via another thread or a dedicated call). // lock memory (via another thread or a dedicated call).
if (buffer->IsVirtual()) { if (buffer->IsVirtual()) {
status_t status = buffer->LockMemory(request->IsWrite()); status_t status = buffer->LockMemory(B_CURRENT_TEAM,
request->IsWrite());
if (status != B_OK) if (status != B_OK)
return status; return status;
} }
@@ -76,13 +76,13 @@ IOBuffer::SetVecs(const iovec* vecs, uint32 count, size_t length, uint32 flags)
status_t status_t
IOBuffer::LockMemory(bool isWrite) IOBuffer::LockMemory(team_id team, bool isWrite)
{ {
for (uint32 i = 0; i < fVecCount; i++) { for (uint32 i = 0; i < fVecCount; i++) {
status_t status = lock_memory(fVecs[i].iov_base, fVecs[i].iov_len, status_t status = lock_memory_etc(team, fVecs[i].iov_base,
isWrite ? 0 : B_READ_DEVICE); fVecs[i].iov_len, isWrite ? 0 : B_READ_DEVICE);
if (status != B_OK) { if (status != B_OK) {
_UnlockMemory(i, isWrite); _UnlockMemory(team, i, isWrite);
return status; return status;
} }
} }
@@ -92,19 +92,19 @@ IOBuffer::LockMemory(bool isWrite)
void 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++) { 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); isWrite ? 0 : B_READ_DEVICE);
} }
} }
void 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) if (fStatus == 1)
fStatus = B_OK; 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 // 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 // following could delete this request, so we don't want to touch it once
// we have started telling others that it is done. // we have started telling others that it is done.
@@ -49,13 +49,14 @@ public:
size_t VecCount() const { return fVecCount; } size_t VecCount() const { return fVecCount; }
size_t Capacity() const { return fCapacity; } size_t Capacity() const { return fCapacity; }
status_t LockMemory(bool isWrite); status_t LockMemory(team_id team, bool isWrite);
void UnlockMemory(bool isWrite); void UnlockMemory(team_id team, bool isWrite);
private: private:
~IOBuffer(); ~IOBuffer();
// not implemented // not implemented
void _UnlockMemory(size_t count, bool isWrite); void _UnlockMemory(team_id team, size_t count,
bool isWrite);
bool fUser; bool fUser;
bool fPhysical; bool fPhysical;