On 04/16/2011 02:11 PM, Zane Bitter wrote: > Signed-off-by: Zane Bitter <zane.bit...@gmail.com> > --- > exec/Makefile.am | 2 - > exec/totembuf.c | 212 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > exec/totembuf.h | 46 ++++++++++++ > exec/totemudp.c | 11 ++- > 4 files changed, 268 insertions(+), 3 deletions(-) > create mode 100644 exec/totembuf.c > create mode 100644 exec/totembuf.h > > diff --git a/exec/Makefile.am b/exec/Makefile.am > index 39a7213..8ee1e07 100644 > --- a/exec/Makefile.am > +++ b/exec/Makefile.am > @@ -37,7 +37,7 @@ INCLUDES = -I$(top_builddir)/include > -I$(top_srcdir)/include $(nss_CFLAGS) $(rd > > TOTEM_SRC = coropoll.c totemip.c totemnet.c totemudp.c \ > totemudpu.c totemrrp.c totemsrp.c totemmrp.c \ > - totempg.c crypto.c wthread.c tsafe.c > + totempg.c totembuf.c crypto.c wthread.c tsafe.c > if BUILD_RDMA > TOTEM_SRC += totemiba.c > endif > diff --git a/exec/totembuf.c b/exec/totembuf.c > new file mode 100644 > index 0000000..2e4895d > --- /dev/null > +++ b/exec/totembuf.c > @@ -0,0 +1,212 @@ > +/* > + * Copyright (c) 2011 Zane Bitter (zane.bit...@gmail.com) > + * > + * All rights reserved. > + * > + * This software licensed under BSD license, the text of which follows: > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * - Redistributions of source code must retain the above copyright notice, > + * this list of conditions and the following disclaimer. > + * - Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * - Neither the name of the MontaVista Software, Inc. nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > + * THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <config.h> > +#include <corosync/list.h> > + > +#include <stddef.h> > +#include <stdlib.h> > +#include <stdint.h> > +#include <assert.h> > +#include <pthread.h> > + > +#include "totembuf.h" > + > + > +#define MAX_FREE_LIST_LENGTH 500 > + > +#define TOTEMBUF_FROM_BUFFER(BUF) ((struct totembuf *)((char *)(BUF) - > offsetof(struct totembuf, buffer))) > + > +#define TOTEMBUF_MAGIC 0xdeadbeefu > + > + > +struct totembuf_list { > + pthread_key_t key; > + size_t size; > +}; > + > +struct totembuf_list_head { > + struct list_head list_free; > + const struct totembuf_list *owner; > + unsigned int length; > +}; > + > +struct totembuf { > + uint32_t magic; > + struct list_head list_free; > + const struct totembuf_list *owner; > + const struct totembuf_list_head *head; > + int reference; > + char buffer[0]; > +}; > + > + > +static void totembuf_free_list_destroy (void *list_head); > + > + > +struct totembuf_list *totembuf_list_init (size_t buffer_size) > +{ > + struct totembuf_list *free_list = malloc (sizeof (struct > totembuf_list)); > + if (!free_list) { > + return NULL; > + } > + > + pthread_key_create (&free_list->key, &totembuf_free_list_destroy); > + free_list->size = buffer_size; > + > + return (free_list); > +} > + > +static struct totembuf_list_head *totembuf_free_list_get ( > + const struct totembuf_list *free_list) > +{ > + struct totembuf_list_head *head; > + > + /* Get the Thread-Local free list head */ > + head = pthread_getspecific (free_list->key); > + > + if (!head) { > + head = malloc (sizeof (*head)); > + if (head) { > + int result; > + > + list_init (&head->list_free); > + head->length = 0; > + head->owner = free_list; > + result = pthread_setspecific (free_list->key, head); > + if (result) { > + free (head); > + return (NULL); > + } > + } > + } > + > + return (head); > +} > + > +static void totembuf_free_list_destroy (void *list_head) > +{ > + struct totembuf_list_head *head = list_head; > + struct list_head *list = head->list_free.next; > + > + assert (head->owner != NULL); > + pthread_setspecific (head->owner->key, NULL); > + > + while (list != &head->list_free) { > + struct totembuf *block = list_entry (list, struct totembuf, > list_free); > + list = list->next; > + > + free (block); > + } > + > + list_init (&head->list_free); > + free (head); > +} > + > +void *totembuf_alloc (const struct totembuf_list *free_list) > +{ > + struct totembuf *block; > + struct totembuf_list_head *head; > + > + head = totembuf_free_list_get (free_list); > + if (list_empty (&head->list_free)) { > + block = malloc (sizeof (struct totembuf) + free_list->size); > + if (block == NULL) { > + return (NULL); > + } > + > + block->magic = TOTEMBUF_MAGIC; > + > + list_init (&block->list_free); > + block->owner = free_list; > + block->head = head; > + } else { > + block = list_entry (head->list_free.next, struct totembuf, > list_free); > + list_del (&block->list_free);
This needs a list_init after the list_del. list_del does not put the list header in a "fresh" state and will result in corruption of the free list. > + head->length--; > + } > + > + block->reference = 0; > + > + return (block->buffer); > +} > + > +void *totembuf_retain (void *ptr) > +{ > + struct totembuf *block = TOTEMBUF_FROM_BUFFER (ptr); > + assert (block->magic == TOTEMBUF_MAGIC); > + > + /* We are not doing full reference counting */ Please use k&r comments /* * comment */ > + assert (block->reference == 0); > + > + block->reference = 1; > + return (block->buffer); > +} > + > +void totembuf_release (void *ptr) > +{ > + struct totembuf *block = TOTEMBUF_FROM_BUFFER (ptr); > + assert (block->magic == TOTEMBUF_MAGIC); > + > + /* We are not doing full reference counting */ > + assert (block->reference != 0); > + > + block->reference = 0; > +} > + > +int totembuf_is_retained (const void *ptr) > +{ > + struct totembuf *block = TOTEMBUF_FROM_BUFFER (ptr); > + assert (block->magic == TOTEMBUF_MAGIC); > + > + return (block->reference); > +} > + > +void totembuf_dealloc (void *ptr) > +{ > + struct totembuf_list_head *head; > + struct totembuf *block = TOTEMBUF_FROM_BUFFER (ptr); > + assert (block->magic == TOTEMBUF_MAGIC); > + > + assert (block->owner != NULL); > + head = totembuf_free_list_get (block->owner); > + > + if (head != block->head || head->length >= MAX_FREE_LIST_LENGTH) { > + /* Allocated from a different thread or the list is already > + * huge, so just free it */ > + free (block); > + } else { > + list_add_tail (&block->list_free, &head->list_free); > + head->length++; > + } > +} > + > diff --git a/exec/totembuf.h b/exec/totembuf.h > new file mode 100644 > index 0000000..c474d73 > --- /dev/null > +++ b/exec/totembuf.h > @@ -0,0 +1,46 @@ > +/* > + * Copyright (c) 2011 Zane Bitter (zane.bit...@gmail.com) > + * > + * All rights reserved. > + * > + * This software licensed under BSD license, the text of which follows: > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * - Redistributions of source code must retain the above copyright notice, > + * this list of conditions and the following disclaimer. > + * - Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * - Neither the name of the MontaVista Software, Inc. nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > + * THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef TOTEMBUF_H_DEFINED > +#define TOTEMBUF_H_DEFINED > + > +struct totembuf_list; > + > +struct totembuf_list *totembuf_list_init (size_t buffer_size); > +void *totembuf_alloc (const struct totembuf_list *free_list); > +void *totembuf_retain (void *ptr); > +void totembuf_release (void *ptr); > +int totembuf_is_retained (const void *ptr); > +void totembuf_dealloc (void *ptr); > + > +#endif > + > diff --git a/exec/totemudp.c b/exec/totemudp.c > index e53a94e..42739d6 100644 > --- a/exec/totemudp.c > +++ b/exec/totemudp.c > @@ -65,6 +65,7 @@ > #include <corosync/totem/coropoll.h> > #define LOGSYS_UTILS_ONLY 1 > #include <corosync/engine/logsys.h> > +#include "totembuf.h" > #include "totemudp.h" > #include "wthread.h" > > @@ -223,6 +224,8 @@ static int totemudp_build_sockets ( > > static struct totem_ip_address localhost; > > +static struct totembuf_list *free_list = NULL; > + > static void totemudp_instance_initialize (struct totemudp_instance *instance) > { > memset (instance, 0, sizeof (struct totemudp_instance)); > @@ -1747,6 +1750,10 @@ int totemudp_initialize ( > { > struct totemudp_instance *instance; > > + if (!free_list) { > + free_list = totembuf_list_init (FRAME_SIZE_MAX); > + } > + > instance = malloc (sizeof (struct totemudp_instance)); > if (instance == NULL) { > return (-1); > @@ -1826,7 +1833,7 @@ int totemudp_initialize ( > > void *totemudp_buffer_alloc (void) > { > - return malloc (FRAME_SIZE_MAX); > + return totembuf_alloc (free_list); > } > > void *totemudp_buffer_retain (void *ptr) > @@ -1840,7 +1847,7 @@ void *totemudp_buffer_retain (void *ptr) > > void totemudp_buffer_release (void *ptr) > { > - return free (ptr); > + totembuf_dealloc (ptr); > } > > int totemudp_processor_count_set ( > > _______________________________________________ > Openais mailing list > Openais@lists.linux-foundation.org > https://lists.linux-foundation.org/mailman/listinfo/openais _______________________________________________ Openais mailing list Openais@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/openais