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);
+               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 */
+       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

Reply via email to