* Removed my old doubly linked list implementation, and stay with Ingo's.

* Adapt other sources where needed (the boot loader's RootFileSystem still
  used the old implementation).
* Implemented RootFileSystem::Rewind().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16889 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-03-27 10:27:05 +00:00
parent a722407264
commit c918a987a0
8 changed files with 71 additions and 167 deletions
+39 -143
View File
@@ -1,7 +1,7 @@
/* /*
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2005-2006, Ingo Weinhold, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Distributed under the terms of the MIT License.
*/ */
#ifndef KERNEL_UTIL_DOUBLY_LINKED_LIST_H #ifndef KERNEL_UTIL_DOUBLY_LINKED_LIST_H
#define KERNEL_UTIL_DOUBLY_LINKED_LIST_H #define KERNEL_UTIL_DOUBLY_LINKED_LIST_H
@@ -12,135 +12,6 @@
#ifdef __cplusplus #ifdef __cplusplus
/* This header defines a doubly-linked list. It differentiates between a link
* and an item.
* It's the C++ version of <util/list.h> it's very small and efficient, but
* has not been perfectly C++-ified yet.
* The link must be part of the item, it cannot be allocated on demand yet.
*/
namespace DoublyLinked {
class Link {
public:
Link *next;
Link *prev;
};
template<class Item, Link Item::* LinkMember = &Item::fLink> class Iterator;
template<class Item, Link Item::* LinkMember = &Item::fLink>
class List {
public:
//typedef typename Item ValueType;
typedef Iterator<Item, LinkMember> IteratorType;
List()
{
fLink.next = fLink.prev = &fLink;
}
void Add(Item *item)
{
//Link *link = &item->*LinkMember;
(item->*LinkMember).next = &fLink;
(item->*LinkMember).prev = fLink.prev;
fLink.prev->next = &(item->*LinkMember);
fLink.prev = &(item->*LinkMember);
}
static void Remove(Item *item)
{
(item->*LinkMember).next->prev = (item->*LinkMember).prev;
(item->*LinkMember).prev->next = (item->*LinkMember).next;
}
Item *RemoveHead()
{
if (IsEmpty())
return NULL;
Item *item = GetItem(fLink.next);
Remove(item);
return item;
}
IteratorType Iterator()
{
return IteratorType(*this);
}
bool IsEmpty()
{
return fLink.next == &fLink;
}
Link *Head()
{
return fLink.next;
}
static inline size_t Offset()
{
return (size_t)&(((Item *)1)->*LinkMember) - 1;
}
static inline Item *GetItem(Link *link)
{
return (Item *)((uint8 *)link - Offset());
}
private:
friend class DoublyLinked::Iterator<Item, LinkMember>;
Link fLink;
};
template<class Item, Link Item::* LinkMember>
class Iterator {
public:
typedef List<Item, LinkMember> ListType;
Iterator() : fCurrent(NULL) {}
Iterator(ListType &list) : fList(&list), fCurrent(list.Head()) {}
Item *Next()
{
if (fCurrent == &fList->fLink)
return NULL;
Link *current = fCurrent;
fCurrent = fCurrent->next;
return ListType::GetItem(current);
}
private:
ListType *fList;
Link *fCurrent;
};
} // namespace DoublyLinked
#endif /* __cplusplus */
#endif /* KERNEL_UTIL_DOUBLY_LINKED_LIST_H */
/*
* Copyright 2005, Ingo Weinhold, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_UTIL_DOUBLY_LINKED_LIST_H
#define _KERNEL_UTIL_DOUBLY_LINKED_LIST_H
#ifdef __cplusplus
#include <SupportDefs.h>
// DoublyLinkedListLink // DoublyLinkedListLink
template<typename Element> template<typename Element>
class DoublyLinkedListLink { class DoublyLinkedListLink {
@@ -225,10 +96,10 @@ public:
class Iterator { class Iterator {
public: public:
Iterator(List *list) Iterator(List *list)
: fList(list), :
fCurrent(NULL), fList(list)
fNext(fList->First())
{ {
Rewind();
} }
Iterator(const Iterator &other) Iterator(const Iterator &other)
@@ -240,7 +111,7 @@ public:
{ {
return fNext; return fNext;
} }
Element *Next() Element *Next()
{ {
fCurrent = fNext; fCurrent = fNext;
@@ -248,7 +119,7 @@ public:
fNext = fList->GetNext(fNext); fNext = fList->GetNext(fNext);
return fCurrent; return fCurrent;
} }
Element *Remove() Element *Remove()
{ {
Element *element = fCurrent; Element *element = fCurrent;
@@ -266,7 +137,13 @@ public:
fNext = other.fNext; fNext = other.fNext;
return *this; return *this;
} }
void Rewind()
{
fCurrent = NULL;
fNext = fList->First();
}
private: private:
List *fList; List *fList;
Element *fCurrent; Element *fCurrent;
@@ -276,9 +153,10 @@ public:
class ConstIterator { class ConstIterator {
public: public:
ConstIterator(const List *list) ConstIterator(const List *list)
: fList(list), :
fNext(list->First()) fList(list)
{ {
Rewind();
} }
ConstIterator(const ConstIterator &other) ConstIterator(const ConstIterator &other)
@@ -290,7 +168,7 @@ public:
{ {
return fNext; return fNext;
} }
Element *Next() Element *Next()
{ {
Element *element = fNext; Element *element = fNext;
@@ -298,14 +176,20 @@ public:
fNext = fList->GetNext(fNext); fNext = fList->GetNext(fNext);
return element; return element;
} }
ConstIterator &operator=(const ConstIterator &other) ConstIterator &operator=(const ConstIterator &other)
{ {
fList = other.fList; fList = other.fList;
fNext = other.fNext; fNext = other.fNext;
return *this; return *this;
} }
void Rewind()
{
fCurrent = NULL;
fNext = fList->First();
}
private: private:
const List *fList; const List *fList;
Element *fNext; Element *fNext;
@@ -334,6 +218,8 @@ public:
inline Element *Head() const { return fFirst; } inline Element *Head() const { return fFirst; }
inline Element *Tail() const { return fLast; } inline Element *Tail() const { return fLast; }
inline Element *RemoveHead();
inline Element *GetPrevious(Element *element) const; inline Element *GetPrevious(Element *element) const;
inline Element *GetNext(Element *element) const; inline Element *GetNext(Element *element) const;
@@ -483,6 +369,16 @@ DOUBLY_LINKED_LIST_CLASS_NAME::RemoveAll()
fLast = NULL; fLast = NULL;
} }
// RemoveHead
DOUBLY_LINKED_LIST_TEMPLATE_LIST
Element *
DOUBLY_LINKED_LIST_CLASS_NAME::RemoveHead()
{
Element *element = Head();
Remove(element);
return element;
}
// GetPrevious // GetPrevious
DOUBLY_LINKED_LIST_TEMPLATE_LIST DOUBLY_LINKED_LIST_TEMPLATE_LIST
Element * Element *
+13 -11
View File
@@ -1,7 +1,7 @@
/* /*
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Distributed under the terms of the MIT License.
*/ */
#include "RootFileSystem.h" #include "RootFileSystem.h"
@@ -32,10 +32,10 @@ RootFileSystem::~RootFileSystem()
status_t status_t
RootFileSystem::Open(void **_cookie, int mode) RootFileSystem::Open(void **_cookie, int mode)
{ {
EntryIterator *iterator = new EntryIterator(fList.Iterator()); EntryIterator *iterator = new (std::nothrow) EntryIterator(&fList);
if (iterator == NULL) if (iterator == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
*_cookie = iterator; *_cookie = iterator;
return B_OK; return B_OK;
@@ -53,7 +53,7 @@ RootFileSystem::Close(void *cookie)
Node * Node *
RootFileSystem::Lookup(const char *name, bool /*traverseLinks*/) RootFileSystem::Lookup(const char *name, bool /*traverseLinks*/)
{ {
EntryIterator iterator = fLinks.Iterator(); EntryIterator iterator = fLinks.GetIterator();
struct entry *entry; struct entry *entry;
// first check the links // first check the links
@@ -67,7 +67,7 @@ RootFileSystem::Lookup(const char *name, bool /*traverseLinks*/)
// then all mounted file systems // then all mounted file systems
iterator = fList.Iterator(); iterator = fList.GetIterator();
while ((entry = iterator.Next()) != NULL) { while ((entry = iterator.Next()) != NULL) {
char entryName[B_OS_NAME_LENGTH]; char entryName[B_OS_NAME_LENGTH];
@@ -116,7 +116,9 @@ RootFileSystem::GetNextNode(void *_cookie, Node **_node)
status_t status_t
RootFileSystem::Rewind(void *_cookie) RootFileSystem::Rewind(void *_cookie)
{ {
// ToDo: implement EntryIterator *iterator = (EntryIterator *)_cookie;
iterator->Rewind();
return B_OK; return B_OK;
} }
@@ -131,7 +133,7 @@ RootFileSystem::IsEmpty()
status_t status_t
RootFileSystem::AddVolume(Directory *volume, Partition *partition) RootFileSystem::AddVolume(Directory *volume, Partition *partition)
{ {
struct entry *entry = new RootFileSystem::entry(); struct entry *entry = new (std::nothrow) RootFileSystem::entry();
if (entry == NULL) if (entry == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -149,7 +151,7 @@ RootFileSystem::AddVolume(Directory *volume, Partition *partition)
status_t status_t
RootFileSystem::AddLink(const char *name, Directory *target) RootFileSystem::AddLink(const char *name, Directory *target)
{ {
struct entry *entry = new RootFileSystem::entry(); struct entry *entry = new (std::nothrow) RootFileSystem::entry();
if (entry == NULL) if (entry == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -166,7 +168,7 @@ RootFileSystem::AddLink(const char *name, Directory *target)
status_t status_t
RootFileSystem::GetPartitionFor(Directory *volume, Partition **_partition) RootFileSystem::GetPartitionFor(Directory *volume, Partition **_partition)
{ {
EntryIterator iterator = fList.Iterator(); EntryIterator iterator = fList.GetIterator();
struct entry *entry; struct entry *entry;
while ((entry = iterator.Next()) != NULL) { while ((entry = iterator.Next()) != NULL) {
+6 -7
View File
@@ -1,7 +1,7 @@
/* /*
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2003-2006, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. * Distributed under the terms of the MIT License.
*/ */
#ifndef ROOT_FILE_SYSTEM_H #ifndef ROOT_FILE_SYSTEM_H
#define ROOT_FILE_SYSTEM_H #define ROOT_FILE_SYSTEM_H
@@ -33,14 +33,13 @@ class RootFileSystem : public Directory {
status_t GetPartitionFor(Directory *volume, Partition **_partition); status_t GetPartitionFor(Directory *volume, Partition **_partition);
private: private:
struct entry { struct entry : public DoublyLinkedListLinkImpl<entry> {
DoublyLinked::Link link;
const char *name; const char *name;
Directory *root; Directory *root;
Partition *partition; Partition *partition;
}; };
typedef DoublyLinked::Iterator<entry, &entry::link> EntryIterator; typedef DoublyLinkedList<entry>::Iterator EntryIterator;
typedef DoublyLinked::List<entry, &entry::link> EntryList; typedef DoublyLinkedList<entry> EntryList;
EntryList fList; EntryList fList;
EntryList fLinks; EntryList fLinks;
@@ -20,6 +20,7 @@
#include <drivers/driver_settings.h> #include <drivers/driver_settings.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
+2
View File
@@ -13,6 +13,8 @@
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/khash.h> #include <util/khash.h>
#include <new>
#include <stdlib.h>
#include <string.h> #include <string.h>
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2005, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2002-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+4 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2005, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2002-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -11,6 +11,7 @@
#include "vfs_select.h" #include "vfs_select.h"
#include <sys/select.h> #include <sys/select.h>
#include <new>
#include <poll.h> #include <poll.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -340,7 +341,7 @@ add_select_sync_pool_entry(select_sync_pool *pool, selectsync *sync,
select_sync_pool_entry *entry = find_select_sync_pool_entry(pool, sync, select_sync_pool_entry *entry = find_select_sync_pool_entry(pool, sync,
ref); ref);
if (!entry) { if (!entry) {
entry = new(nothrow) select_sync_pool_entry; entry = new (std::nothrow) select_sync_pool_entry;
if (!entry) if (!entry)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -364,7 +365,7 @@ add_select_sync_pool_entry(select_sync_pool **_pool, selectsync *sync,
// create the pool, if necessary // create the pool, if necessary
select_sync_pool *pool = *_pool; select_sync_pool *pool = *_pool;
if (!pool) { if (!pool) {
pool = new(nothrow) select_sync_pool; pool = new (std::nothrow) select_sync_pool;
if (!pool) if (!pool)
return B_NO_MEMORY; return B_NO_MEMORY;
+5 -2
View File
@@ -1,11 +1,10 @@
/* /*
* Copyright 2005, Axel Dörfler, [email protected]. * Copyright 2005-2006, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <KernelExport.h> #include <KernelExport.h>
#include <signal.h>
#include <vm_low_memory.h> #include <vm_low_memory.h>
#include <vm_page.h> #include <vm_page.h>
@@ -13,6 +12,10 @@
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <new>
#include <signal.h>
#include <stdlib.h>
//#define TRACE_LOW_MEMORY //#define TRACE_LOW_MEMORY
#ifdef TRACE_LOW_MEMORY #ifdef TRACE_LOW_MEMORY