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:
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2004, Axel Dörfler, [email protected]. 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();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2004, Axel Dörfler, [email protected]. 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 */
|
||||||
Reference in New Issue
Block a user