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

Reply via email to