- Fix the snbuffers recycling mechanism. Park function was not parking if the queue was empty at first instance. Fetching caused corruption freeing the previous buffer of the best matching one.

- Add debug methods



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29628 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Ruiz Dorantes
2009-03-21 15:35:22 +00:00
parent 55c030c4e2
commit a99504cae3
2 changed files with 38 additions and 22 deletions
@@ -9,6 +9,7 @@
#include <malloc.h>
#include <string.h>
#include <KernelExport.h>
struct snet_buffer {
struct list_link link;
@@ -162,8 +163,7 @@ inline uint16 snb_remaining_to_pull(snet_buffer* snb)
static snet_buffer*
snb_attempt_reuse(snet_buffer* snb, uint16 size)
{
if ( snb == NULL ||
((int16)snb->allocatedSize - (int16)size) < 0 ) {
if ( snb == NULL || (snb->allocatedSize < size) ) {
/* Impossible or not worth, Creating a new one */
snb_free(snb);
@@ -182,11 +182,17 @@ void
snb_park(struct list* l, snet_buffer* snb)
{
snet_buffer* item = NULL;
/* insert it by order */
while ((item = list_get_next_item(l, item)) != NULL) {
if (item->allocatedSize > snb->allocatedSize)
/* This one has allocated more than us place us back*/
if (item->allocatedSize > snb->allocatedSize) {
list_insert_item_before(l, item, snb);
return;
}
}
/* no buffer bigger than us(or empty).. then at the end*/
list_add_item(l, snb);
}
@@ -194,29 +200,42 @@ snet_buffer*
snb_fetch(struct list* l, uint16 size)
{
snet_buffer* item = NULL;
snet_buffer* previous = NULL;
snet_buffer* newitem = NULL;
if (!list_is_empty(l))
while ((item = list_get_next_item(l, item)) != NULL) {
if (item->allocatedSize == size) {
if (item->allocatedSize >= size) {
/* This one is for us*/
break;
}
else if (item->allocatedSize > size) {
/* get the previous*/
item = previous;
break;
}
previous = item;
}
// reusing previous pointer for another proposit
previous = snb_attempt_reuse(item, size);
newitem = snb_attempt_reuse(item, size);
/* the resulting reused one is the same as we fetched? => remove it from list*/
if (item == previous) {
if (item == newitem) {
list_remove_item(l, item);
}
return previous;
return newitem;
}
uint16
snb_packets(struct list* l)
{
uint16 count = 0;
snet_buffer* item = NULL;
while ((item = list_get_next_item(l, item)) != NULL)
count++;
return count;
}
void
snb_dump(snet_buffer* snb)
{
kprintf("item=%p\tprev=%p\tnext=%p\tallocated=%d\n", snb, snb->link.prev, snb->link.next, snb->allocatedSize);
}
@@ -1,11 +1,7 @@
/*
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
*
* All rights reserved. Distributed under the terms of the MIT License.
*
*/
#ifndef _SNET_BUFFER_H_
#define _SNET_BUFFER_H_
@@ -75,7 +71,8 @@ uint16 snb_remaining_to_pull(snet_buffer* snb);
*/
void snb_park(struct list* l, snet_buffer* snb);
snet_buffer* snb_fetch(struct list* l, uint16 size);
uint16 snb_packets(struct list* l);
void snb_dump(snet_buffer* snb);
#endif