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 <[email protected]>
>> ---
>> 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 ([email protected])
>> + *
>> + * 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.
> 
>> +            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
> */

Ah, yeah, completely forgot. Thanks.

>> +    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 ([email protected])
>> + *
>> + * 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
>> [email protected]
>> https://lists.linux-foundation.org/mailman/listinfo/openais
> 

_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to