Implemented the basic I/O scheduler architecture - doesn't schedule anything

yet, though (instead, it directly performs all requests, so there is no
functional difference to the previous mechanism).
devfs and the file cache will directly access the I/O scheduler. There is
one scheduler per raw disk device; devfs detects that automatically, and
all I/O will go through the scheduler, then.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8683 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-08-28 13:28:29 +00:00
parent a0c7b77db3
commit d3efd9a6ef
2 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,116 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include "IOScheduler.h"
#include <KernelExport.h>
#include <khash.h>
#include <lock.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
IORequest::IORequest(void *_cookie, off_t _offset, void *_buffer, size_t _size, bool _writeMode)
:
cookie(_cookie),
virtual_address(addr_t(_buffer)),
offset(_offset),
size(_size),
write(_writeMode)
{
}
IORequest::IORequest(void *_cookie, off_t _offset, const void *_buffer, size_t _size, bool _writeMode)
:
cookie(_cookie),
virtual_address(addr_t(const_cast<void *>(_buffer))),
offset(_offset),
size(_size),
write(_writeMode)
{
}
// #pragma mark -
IOScheduler::IOScheduler(const char *name, device_hooks *hooks)
:
fDeviceHooks(hooks)
{
mutex_init(&fLock, "I/O scheduler queue");
// start thread for device
fThread = spawn_kernel_thread(&IOScheduler::scheduler, name, B_NORMAL_PRIORITY, (void *)this);
#if 0
if (fThread >= B_OK)
resume_thread(fThread);
#endif
}
IOScheduler::~IOScheduler()
{
kill_thread(fThread);
mutex_destroy(&fLock);
}
status_t
IOScheduler::InitCheck() const
{
if (fLock.sem < B_OK)
return fLock.sem;
if (fThread < B_OK)
return fThread;
return B_OK;
}
status_t
IOScheduler::Process(IORequest &request)
{
// ToDo: put the request into the queue, and wait until it got processed by the scheduler
// ToDo: translate addresses into physical locations
// ToDo: connect to the DPC mechanism in the SCSI/IDE bus manager?
// ToDo: assume locked memory?
if (request.write)
return fDeviceHooks->write(request.cookie, request.offset, (const void *)request.virtual_address, &request.size);
return fDeviceHooks->read(request.cookie, request.offset, (void *)request.virtual_address, &request.size);
}
#if 0
IOScheduler *
IOScheduler::GetScheduler()
{
return NULL;
}
#endif
int32
IOScheduler::Scheduler()
{
// main loop
}
int32
IOScheduler::scheduler(void *_self)
{
IOScheduler *self = (IOScheduler *)_self;
return self->Scheduler();
}

View File

@ -0,0 +1,59 @@
/*
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#ifndef IO_SCHEDULER_H
#define IO_SCHEDULER_H
#include <OS.h>
#include <Drivers.h>
#include <util/DoublyLinkedList.h>
#include <lock.h>
class IORequest {
public:
IORequest(void *cookie, off_t offset, void *buffer, size_t size, bool write = false);
IORequest(void *cookie, off_t offset, const void *buffer, size_t size, bool write = true);
// ToDo: iovecs version?
size_t Size() const { return size; }
DoublyLinked::Link link;
void *cookie;
addr_t physical_address;
addr_t virtual_address;
off_t offset;
size_t size;
bool write;
thread_id thread;
};
class IOScheduler {
public:
IOScheduler(const char *name, device_hooks *hooks);
~IOScheduler();
status_t InitCheck() const;
status_t Process(IORequest &request);
#if 0
static IOScheduler *GetScheduler();
#endif
private:
int32 Scheduler();
static int32 scheduler(void *);
private:
device_hooks *fDeviceHooks;
mutex fLock;
thread_id fThread;
DoublyLinked::List<IORequest, &IORequest::link> fRequests;
};
#endif /* IO_SCHEDULER_H */