On 04/18/2011 08:07 PM, Zane Bitter wrote:
> 
> On 2011/04/18, at 16:17, Steven Dake wrote:
> 
>> 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.
> 
> Well spotted, thanks. I didn't notice anything that looked like corruption 
> when I was testing, I suspect because the list_add doesn't look at the 
> contents of the new entry when you re-add it to the free list. But I totally 
> agree that it's much better to have it in a defined state when it's floating 
> around allocated.
>>

I found it via valgrind when running in iba mode.
_______________________________________________
Openais mailing list
Openais@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to