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