* Made some internal lists use DoublyLinkedLists instead of struct list.

* Added a few KDL commands to improve your debugging experience.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35469 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-02-15 13:28:33 +00:00
parent 965abdebd5
commit a3ec278add
5 changed files with 191 additions and 41 deletions
+79 -33
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved. * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -32,8 +32,13 @@
# define TRACE(x) ; # define TRACE(x) ;
#endif #endif
#define ENABLE_DEBUGGER_COMMANDS 1
typedef DoublyLinkedList<net_domain_private> DomainList;
static mutex sDomainLock; static mutex sDomainLock;
static list sDomains; static DomainList sDomains;
/*! Scans the domain list for the specified family. /*! Scans the domain list for the specified family.
@@ -42,12 +47,8 @@ static list sDomains;
static net_domain_private* static net_domain_private*
lookup_domain(int family) lookup_domain(int family)
{ {
net_domain_private* domain = NULL; DomainList::Iterator iterator = sDomains.GetIterator();
while (true) { while (net_domain_private* domain = iterator.Next()) {
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
if (domain->family == family) if (domain->family == family)
return domain; return domain;
} }
@@ -56,6 +57,55 @@ lookup_domain(int family)
} }
#if ENABLE_DEBUGGER_COMMANDS
static int
dump_domains(int argc, char** argv)
{
DomainList::Iterator iterator = sDomains.GetIterator();
while (net_domain_private* domain = iterator.Next()) {
kprintf("domain: %p, %s, %d\n", domain, domain->name, domain->family);
kprintf(" module: %p\n", domain->module);
kprintf(" address_module: %p\n", domain->address_module);
if (!list_is_empty(&domain->interfaces))
kprintf(" interfaces:\n");
net_interface* interface = NULL;
while (true) {
interface = (net_interface*)list_get_next_item(&domain->interfaces,
interface);
if (interface == NULL)
break;
kprintf(" %p\n", interface);
}
if (!domain->routes.IsEmpty())
kprintf(" routes:\n");
RouteList::Iterator routeIterator = domain->routes.GetIterator();
while (net_route* route = routeIterator.Next()) {
kprintf(" %p\n", route);
}
if (!domain->route_infos.IsEmpty())
kprintf(" route infos:\n");
RouteInfoList::Iterator infoIterator = domain->route_infos.GetIterator();
while (net_route_info* info = infoIterator.Next()) {
kprintf(" %p\n", info);
}
}
return 0;
}
#endif // ENABLE_DEBUGGER_COMMANDS
// #pragma mark - // #pragma mark -
@@ -74,14 +124,10 @@ count_domain_interfaces()
{ {
MutexLocker locker(sDomainLock); MutexLocker locker(sDomainLock);
net_domain_private* domain = NULL;
uint32 count = 0; uint32 count = 0;
while (true) { DomainList::Iterator iterator = sDomains.GetIterator();
domain = (net_domain_private*)list_get_next_item(&sDomains, domain); while (net_domain_private* domain = iterator.Next()) {
if (domain == NULL)
break;
net_interface* interface = NULL; net_interface* interface = NULL;
while (true) { while (true) {
interface = (net_interface*)list_get_next_item(&domain->interfaces, interface = (net_interface*)list_get_next_item(&domain->interfaces,
@@ -97,8 +143,7 @@ count_domain_interfaces()
} }
/*! /*! Dumps a list of all interfaces into the supplied userland buffer.
Dumps a list of all interfaces into the supplied userland buffer.
If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is
returned. returned.
*/ */
@@ -108,13 +153,9 @@ list_domain_interfaces(void* _buffer, size_t* bufferSize)
MutexLocker locker(sDomainLock); MutexLocker locker(sDomainLock);
UserBuffer buffer(_buffer, *bufferSize); UserBuffer buffer(_buffer, *bufferSize);
net_domain_private* domain = NULL;
while (true) {
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
DomainList::Iterator iterator = sDomains.GetIterator();
while (net_domain_private* domain = iterator.Next()) {
RecursiveLocker locker(domain->lock); RecursiveLocker locker(domain->lock);
net_interface* interface = NULL; net_interface* interface = NULL;
@@ -193,8 +234,7 @@ add_interface_to_domain(net_domain* _domain,
} }
/*! /*! Removes the interface from its domain, and deletes it.
Removes the interface from its domain, and deletes it.
You need to hold the domain's lock when calling this function. You need to hold the domain's lock when calling this function.
*/ */
status_t status_t
@@ -281,12 +321,8 @@ domain_removed_device_interface(net_device_interface* deviceInterface)
{ {
MutexLocker locker(sDomainLock); MutexLocker locker(sDomainLock);
net_domain_private* domain = NULL; DomainList::Iterator iterator = sDomains.GetIterator();
while (true) { while (net_domain_private* domain = iterator.Next()) {
domain = (net_domain_private*)list_get_next_item(&sDomains, domain);
if (domain == NULL)
break;
RecursiveLocker locker(domain->lock); RecursiveLocker locker(domain->lock);
net_interface_private* interface = find_interface(domain, net_interface_private* interface = find_interface(domain,
@@ -325,7 +361,7 @@ register_domain(int family, const char* name,
list_init(&domain->interfaces); list_init(&domain->interfaces);
list_add_item(&sDomains, domain); sDomains.Add(domain);
*_domain = domain; *_domain = domain;
return B_OK; return B_OK;
@@ -341,7 +377,7 @@ unregister_domain(net_domain* _domain)
net_domain_private* domain = (net_domain_private*)_domain; net_domain_private* domain = (net_domain_private*)_domain;
MutexLocker locker(sDomainLock); MutexLocker locker(sDomainLock);
list_remove_item(&sDomains, domain); sDomains.Remove(domain);
net_interface_private* interface = NULL; net_interface_private* interface = NULL;
while (true) { while (true) {
@@ -364,7 +400,13 @@ init_domains()
{ {
mutex_init(&sDomainLock, "net domains"); mutex_init(&sDomainLock, "net domains");
list_init_etc(&sDomains, offsetof(struct net_domain_private, link)); new (&sDomains) DomainList;
// static C++ objects are not initialized in the module startup
#if ENABLE_DEBUGGER_COMMANDS
add_debugger_command("net_domains", &dump_domains,
"Dump network domains");
#endif
return B_OK; return B_OK;
} }
@@ -372,6 +414,10 @@ init_domains()
status_t status_t
uninit_domains() uninit_domains()
{ {
#if ENABLE_DEBUGGER_COMMANDS
remove_debugger_command("net_domains", &dump_domains);
#endif
mutex_destroy(&sDomainLock); mutex_destroy(&sDomainLock);
return B_OK; return B_OK;
} }
+6 -6
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved. * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -9,19 +9,18 @@
#define DOMAINS_H #define DOMAINS_H
#include "routes.h"
#include <lock.h> #include <lock.h>
#include <util/list.h> #include <util/list.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include "routes.h"
struct net_device_interface; struct net_device_interface;
struct net_domain_private : net_domain { struct net_domain_private : net_domain,
struct list_link link; DoublyLinkedListLinkImpl<net_domain_private> {
recursive_lock lock; recursive_lock lock;
RouteList routes; RouteList routes;
@@ -47,4 +46,5 @@ status_t register_domain(int family, const char* name,
struct net_address_module_info* addressModule, net_domain* *_domain); struct net_address_module_info* addressModule, net_domain* *_domain);
status_t unregister_domain(net_domain* domain); status_t unregister_domain(net_domain* domain);
#endif // DOMAINS_H #endif // DOMAINS_H
@@ -33,6 +33,8 @@
# define TRACE(x) ; # define TRACE(x) ;
#endif #endif
#define ENABLE_DEBUGGER_COMMANDS 1
static mutex sInterfaceLock; static mutex sInterfaceLock;
static DeviceInterfaceList sInterfaces; static DeviceInterfaceList sInterfaces;
@@ -180,6 +182,93 @@ notify_device_monitors(net_device_interface* interface, int32 event)
} }
#if ENABLE_DEBUGGER_COMMANDS
static int
dump_interface(int argc, char** argv)
{
if (argc != 2) {
kprintf("usage: %s [address]\n", argv[0]);
return 0;
}
net_interface_private* interface
= (net_interface_private*)parse_expression(argv[1]);
kprintf("name: %s\n", interface->name);
kprintf("base_name: %s\n", interface->name);
kprintf("domain: %p\n", interface->domain);
kprintf("device: %p\n", interface->device);
kprintf("device_interface: %p\n", interface->device_interface);
kprintf("direct_route: %p\n", &interface->direct_route);
kprintf("first_protocol: %p\n", interface->first_protocol);
kprintf("first_info: %p\n", interface->first_info);
kprintf("address: %p\n", interface->address);
kprintf("destination: %p\n", interface->destination);
kprintf("mask: %p\n", interface->mask);
kprintf("index: %" B_PRIu32 "\n", interface->index);
kprintf("flags: %#" B_PRIx32 "\n", interface->flags);
kprintf("type: %u\n", interface->type);
kprintf("mtu: %" B_PRIu32 "\n", interface->mtu);
kprintf("metric: %" B_PRIu32 "\n", interface->metric);
return 0;
}
static int
dump_device_interface(int argc, char** argv)
{
if (argc != 2) {
kprintf("usage: %s [address]\n", argv[0]);
return 0;
}
net_device_interface* interface
= (net_device_interface*)parse_expression(argv[1]);
kprintf("device: %p\n", interface->device);
kprintf("reader_thread: %ld\n", interface->reader_thread);
kprintf("up_count: %" B_PRIu32 "\n", interface->up_count);
kprintf("ref_count: %" B_PRId32 "\n", interface->ref_count);
kprintf("deframe_func: %p\n", interface->deframe_func);
kprintf("deframe_ref_count: %" B_PRId32 "\n", interface->ref_count);
kprintf("monitor_funcs:\n");
kprintf("receive_funcs:\n");
kprintf("consumer_thread: %ld\n", interface->consumer_thread);
kprintf("receive_lock: %p\n", &interface->receive_lock);
kprintf("receive_queue: %p\n", &interface->receive_queue);
DeviceMonitorList::Iterator monitorIterator
= interface->monitor_funcs.GetIterator();
while (monitorIterator.HasNext())
kprintf(" %p\n", monitorIterator.Next());
DeviceHandlerList::Iterator handlerIterator
= interface->receive_funcs.GetIterator();
while (handlerIterator.HasNext())
kprintf(" %p\n", handlerIterator.Next());
return 0;
}
static int
dump_device_interfaces(int argc, char** argv)
{
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
while (net_device_interface* interface = iterator.Next()) {
kprintf(" %p\n", interface);
}
return 0;
}
#endif // ENABLE_DEBUGGER_COMMANDS
// #pragma mark - interfaces // #pragma mark - interfaces
@@ -806,6 +895,15 @@ init_interfaces()
new (&sInterfaces) DeviceInterfaceList; new (&sInterfaces) DeviceInterfaceList;
// static C++ objects are not initialized in the module startup // static C++ objects are not initialized in the module startup
#if ENABLE_DEBUGGER_COMMANDS
add_debugger_command("net_interface", &dump_interface,
"Dump the given network interface");
add_debugger_command("net_device_interface", &dump_device_interface,
"Dump the given network device interface");
add_debugger_command("net_device_interfaces", &dump_device_interfaces,
"Dump network device interfaces");
#endif
return B_OK; return B_OK;
} }
@@ -813,6 +911,12 @@ init_interfaces()
status_t status_t
uninit_interfaces() uninit_interfaces()
{ {
#if ENABLE_DEBUGGER_COMMANDS
remove_debugger_command("net_interface", &dump_interface);
remove_debugger_command("net_device_interface", &dump_device_interface);
remove_debugger_command("net_device_interfaces", &dump_device_interfaces);
#endif
mutex_destroy(&sInterfaceLock); mutex_destroy(&sInterfaceLock);
return B_OK; return B_OK;
} }
@@ -15,7 +15,7 @@
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
struct net_device_handler : public DoublyLinkedListLinkImpl<net_device_handler> { struct net_device_handler : DoublyLinkedListLinkImpl<net_device_handler> {
net_receive_func func; net_receive_func func;
int32 type; int32 type;
void* cookie; void* cookie;
@@ -43,7 +43,7 @@
// maximum implementation derived buffer size is 65536 // maximum implementation derived buffer size is 65536
#define ENABLE_DEBUGGER_COMMANDS 1 #define ENABLE_DEBUGGER_COMMANDS 1
//#define ENABLE_STATS 1 #define ENABLE_STATS 1
#define PARANOID_BUFFER_CHECK NET_BUFFER_PARANOIA #define PARANOID_BUFFER_CHECK NET_BUFFER_PARANOIA
#define COMPONENT_PARANOIA_LEVEL NET_BUFFER_PARANOIA #define COMPONENT_PARANOIA_LEVEL NET_BUFFER_PARANOIA