* Started a file_map test app.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30957 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
584ba8989e
commit
503e56854f
7
src/tests/system/kernel/cache/Jamfile
vendored
7
src/tests/system/kernel/cache/Jamfile
vendored
@ -21,7 +21,12 @@ SimpleTest block_cache_test :
|
||||
block_cache_test.cpp
|
||||
: libkernelland_emu.so ;
|
||||
|
||||
SimpleTest file_map_test :
|
||||
file_map_test.cpp
|
||||
file_map.cpp
|
||||
: libkernelland_emu.so ;
|
||||
|
||||
SimpleTest pages_io_test :
|
||||
pages_io_test.cpp
|
||||
;
|
||||
;
|
||||
|
||||
|
318
src/tests/system/kernel/cache/file_map_test.cpp
vendored
Normal file
318
src/tests/system/kernel/cache/file_map_test.cpp
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <fs_cache.h>
|
||||
#include <fs_interface.h>
|
||||
|
||||
#include <file_cache.h>
|
||||
|
||||
|
||||
#define MAX_VECS 32
|
||||
|
||||
|
||||
class Map {
|
||||
public:
|
||||
Map(const char* name, off_t size);
|
||||
~Map();
|
||||
|
||||
void SetTo(const char* name, off_t size);
|
||||
|
||||
Map& Add(off_t offset, off_t length, off_t diskOffset);
|
||||
Map& Clear();
|
||||
Map& SetSize(off_t size);
|
||||
void Invalidate(off_t start, off_t size);
|
||||
void SetMode(uint32 mode);
|
||||
void Test();
|
||||
|
||||
status_t GetFileMap(off_t offset, off_t length, file_io_vec* vecs,
|
||||
size_t* _vecCount);
|
||||
|
||||
private:
|
||||
void _Error(const char* format, ...);
|
||||
void _Verbose(const char* format, ...);
|
||||
int32 _IndexFor(off_t offset);
|
||||
|
||||
const char* fName;
|
||||
uint32 fTest;
|
||||
void* fMap;
|
||||
off_t fOffsets[MAX_VECS];
|
||||
file_io_vec fVecs[MAX_VECS];
|
||||
file_io_vec fTestVecs[MAX_VECS];
|
||||
uint32 fCount;
|
||||
uint32 fTestCount;
|
||||
off_t fTestOffset;
|
||||
off_t fTestLength;
|
||||
off_t fSize;
|
||||
};
|
||||
|
||||
|
||||
static bool sVerbose;
|
||||
|
||||
|
||||
Map::Map(const char* name, off_t size)
|
||||
:
|
||||
fName(NULL),
|
||||
fMap(NULL),
|
||||
fCount(0),
|
||||
fSize(0)
|
||||
{
|
||||
SetTo(name, size);
|
||||
}
|
||||
|
||||
|
||||
Map::~Map()
|
||||
{
|
||||
file_map_delete(fMap);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Map::SetTo(const char* name, off_t size)
|
||||
{
|
||||
file_map_delete(fMap);
|
||||
|
||||
fMap = file_map_create((dev_t)this, 0, size);
|
||||
if (fMap == NULL)
|
||||
_Error("Creating file map failed.");
|
||||
|
||||
fName = name;
|
||||
fSize = size;
|
||||
fCount = 0;
|
||||
fTest = 0;
|
||||
|
||||
printf("Running %s\n", fName);
|
||||
}
|
||||
|
||||
|
||||
Map&
|
||||
Map::Add(off_t offset, off_t length, off_t diskOffset)
|
||||
{
|
||||
_Verbose(" Add(): offset %lld, length %lld, diskOffset %lld", offset,
|
||||
length, diskOffset);
|
||||
|
||||
if (fCount < MAX_VECS) {
|
||||
fOffsets[fCount] = offset;
|
||||
fVecs[fCount].offset = diskOffset;
|
||||
fVecs[fCount].length = length;
|
||||
fCount++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Map&
|
||||
Map::Clear()
|
||||
{
|
||||
_Verbose(" Clear()");
|
||||
fCount = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Map&
|
||||
Map::SetSize(off_t size)
|
||||
{
|
||||
_Verbose(" SetSize(): size %lld", size);
|
||||
file_map_set_size(fMap, size);
|
||||
fSize = size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Map::Invalidate(off_t start, off_t size)
|
||||
{
|
||||
_Verbose(" Invalidate(): start %lld, size %lld", start, size);
|
||||
file_map_invalidate(fMap, start, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Map::SetMode(uint32 mode)
|
||||
{
|
||||
file_map_set_mode(fMap, mode);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Map::Test()
|
||||
{
|
||||
printf(" Test %lu\n", ++fTest);
|
||||
|
||||
for (off_t offset = 0; offset < fSize; offset += 256) {
|
||||
fTestOffset = offset;
|
||||
fTestLength = 256;
|
||||
fTestCount = MAX_VECS;
|
||||
status_t status = file_map_translate(fMap, offset, fTestLength,
|
||||
fTestVecs, &fTestCount, 0);
|
||||
if (status != B_OK) {
|
||||
_Error("file_map_translate(offset %lld) failed: %s", offset,
|
||||
strerror(status));
|
||||
}
|
||||
|
||||
int32 index = _IndexFor(offset);
|
||||
if (index < 0)
|
||||
_Error("index for offset %lld not found!", offset);
|
||||
|
||||
off_t diff = offset - fOffsets[index];
|
||||
|
||||
if (fTestVecs[0].length > fSize - diff) {
|
||||
_Error("size too large: got %lld, size is %lld",
|
||||
fTestVecs[0].length, fSize);
|
||||
}
|
||||
if (fTestVecs[0].offset != fVecs[index].offset + diff) {
|
||||
_Error("offset mismatch: got %lld, should be %lld",
|
||||
fTestVecs[0].offset, fVecs[index].offset + diff);
|
||||
}
|
||||
}
|
||||
|
||||
fTestCount = 0;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Map::GetFileMap(off_t offset, off_t length, file_io_vec* vecs,
|
||||
size_t* _vecCount)
|
||||
{
|
||||
int32 index = _IndexFor(offset);
|
||||
if (index < 0)
|
||||
_Error("No vec for offset %lld\n", offset);
|
||||
|
||||
_Verbose(" GetFileMap(): offset: %lld, length: %lld, index %ld", offset,
|
||||
length, index);
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
while (length > 0) {
|
||||
if (count >= *_vecCount)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
if ((uint32)index >= fCount)
|
||||
return B_OK;
|
||||
|
||||
off_t diff = offset - fOffsets[index];
|
||||
vecs[count].offset = fVecs[index].offset + diff;
|
||||
vecs[count].length = fVecs[index].length - diff;
|
||||
_Verbose(" [%lu] offset %lld, length %lld", count,
|
||||
vecs[count].offset, vecs[count].length);
|
||||
|
||||
length -= vecs[count].length;
|
||||
offset += vecs[count].length;
|
||||
index++;
|
||||
count++;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Map::_Error(const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
fprintf(stderr, "ERROR %s: ", fName);
|
||||
vfprintf(stderr, format, args);
|
||||
fputc('\n', stderr);
|
||||
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, " size %lld\n", fSize);
|
||||
|
||||
for (uint32 i = 0; i < fCount; i++) {
|
||||
fprintf(stderr, " [%lu] offset %lld, length %lld, disk offset %lld\n",
|
||||
i, fOffsets[i], fVecs[i].length, fVecs[i].offset);
|
||||
}
|
||||
|
||||
if (fTestCount > 0) {
|
||||
fprintf(stderr, "got for offset %lld, length %lld:\n",
|
||||
fTestOffset, fTestLength);
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < fTestCount; i++) {
|
||||
fprintf(stderr, " [%lu] offset %lld, length %lld\n",
|
||||
i, fTestVecs[i].offset, fTestVecs[i].length);
|
||||
}
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
debugger("file map error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Map::_Verbose(const char* format, ...)
|
||||
{
|
||||
if (!sVerbose)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
vprintf(format, args);
|
||||
putchar('\n');
|
||||
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Map::_IndexFor(off_t offset)
|
||||
{
|
||||
for (uint32 i = 0; i < fCount; i++) {
|
||||
if (offset >= fOffsets[i] && offset < fOffsets[i] + fVecs[i].length)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - VFS support functions
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
vfs_get_file_map(struct vnode* vnode, off_t offset, uint32 length,
|
||||
file_io_vec* vecs, size_t* _vecCount)
|
||||
{
|
||||
Map* map = (Map*)vnode;
|
||||
return map->GetFileMap(offset, length, vecs, _vecCount);
|
||||
}
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
vfs_lookup_vnode(dev_t mountID, ino_t vnodeID, struct vnode** _vnode)
|
||||
{
|
||||
*_vnode = (struct vnode*)mountID;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
file_map_init();
|
||||
sVerbose = true;
|
||||
|
||||
Map map("shrink1", 4096);
|
||||
map.Add(0, 1024, 4096).Add(1024, 3072, 8192);
|
||||
map.Test();
|
||||
map.SetSize(0).Clear();
|
||||
map.Test();
|
||||
map.Add(0, 8192, 1000).SetSize(7777);
|
||||
map.Test();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user