[Haiku-commits] r30957 - haiku/trunk/src/tests/system/kernel/cache

axeld at mail.berlios.de axeld at mail.berlios.de
Thu Jun 4 12:50:12 CEST 2009


Author: axeld
Date: 2009-06-04 12:50:09 +0200 (Thu, 04 Jun 2009)
New Revision: 30957
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=30957&view=rev

Added:
   haiku/trunk/src/tests/system/kernel/cache/file_map_test.cpp
Modified:
   haiku/trunk/src/tests/system/kernel/cache/Jamfile
Log:
* Started a file_map test app.


Modified: haiku/trunk/src/tests/system/kernel/cache/Jamfile
===================================================================
--- haiku/trunk/src/tests/system/kernel/cache/Jamfile	2009-06-04 09:57:31 UTC (rev 30956)
+++ haiku/trunk/src/tests/system/kernel/cache/Jamfile	2009-06-04 10:50:09 UTC (rev 30957)
@@ -21,7 +21,12 @@
 	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
-	;
+;
 

Added: haiku/trunk/src/tests/system/kernel/cache/file_map_test.cpp
===================================================================
--- haiku/trunk/src/tests/system/kernel/cache/file_map_test.cpp	2009-06-04 09:57:31 UTC (rev 30956)
+++ haiku/trunk/src/tests/system/kernel/cache/file_map_test.cpp	2009-06-04 10:50:09 UTC (rev 30957)
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2009, Axel Dörfler, axeld at 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;
+}




More information about the Haiku-commits mailing list