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:
parent
a0c7b77db3
commit
d3efd9a6ef
116
src/kernel/core/fs/IOScheduler.cpp
Normal file
116
src/kernel/core/fs/IOScheduler.cpp
Normal 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();
|
||||
}
|
||||
|
59
src/kernel/core/fs/IOScheduler.h
Normal file
59
src/kernel/core/fs/IOScheduler.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user