From c8d9d05e7a3b7b30dae6dd4bea0925162c8d8e33 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Mon, 22 Jan 2018 22:34:26 -0800 Subject: [PATCH] tlv: Implement a memory pool for TLV descriptors. Signed-off-by: Richard Cochran --- msg.c | 3 +++ tlv.c | 32 ++++++++++++++++++++++++++++++++ tlv.h | 21 +++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/msg.c b/msg.c index 6943431..52a59e7 100644 --- a/msg.c +++ b/msg.c @@ -213,6 +213,9 @@ void msg_cleanup(void) { struct message_storage *s; struct ptp_message *m; + + tlv_extra_cleanup(); + while ((m = TAILQ_FIRST(&msg_pool)) != NULL) { TAILQ_REMOVE(&msg_pool, m, list); s = container_of(m, struct message_storage, msg); diff --git a/tlv.c b/tlv.c index a5c2eb3..aa4dafa 100644 --- a/tlv.c +++ b/tlv.c @@ -18,6 +18,7 @@ */ #include #include +#include #include #include "port.h" @@ -29,6 +30,9 @@ uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE }; +static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool = + TAILQ_HEAD_INITIALIZER(tlv_pool); + static void scaled_ns_n2h(ScaledNs *sns) { sns->nanoseconds_msb = ntohs(sns->nanoseconds_msb); @@ -412,6 +416,34 @@ static void org_pre_send(struct organization_tlv *org) } } +struct tlv_extra *tlv_extra_alloc(void) +{ + struct tlv_extra *extra = TAILQ_FIRST(&tlv_pool); + + if (extra) { + TAILQ_REMOVE(&tlv_pool, extra, list); + } else { + extra = calloc(1, sizeof(*extra)); + } + return extra; +} + +void tlv_extra_cleanup(void) +{ + struct tlv_extra *extra; + + while ((extra = TAILQ_FIRST(&tlv_pool)) != NULL) { + TAILQ_REMOVE(&tlv_pool, extra, list); + free(extra); + } +} + +void tlv_extra_recycle(struct tlv_extra *extra) +{ + memset(extra, 0, sizeof(*extra)); + TAILQ_INSERT_HEAD(&tlv_pool, extra, list); +} + int tlv_post_recv(struct TLV *tlv, struct tlv_extra *extra) { int result = 0; diff --git a/tlv.h b/tlv.h index c345afe..fd41022 100644 --- a/tlv.h +++ b/tlv.h @@ -20,6 +20,8 @@ #ifndef HAVE_TLV_H #define HAVE_TLV_H +#include + #include "ddt.h" #include "ds.h" @@ -228,11 +230,30 @@ struct mgmt_clock_description { }; struct tlv_extra { + TAILQ_ENTRY(tlv_extra) list; + struct TLV *tlv; union { struct mgmt_clock_description cd; }; }; +/** + * Allocates a new tlv_extra structure. + * @return Pointer to a new structure on success or NULL otherwise. + */ +struct tlv_extra *tlv_extra_alloc(void); + +/** + * Release all of the memory in the tlv_extra cache. + */ +void tlv_extra_cleanup(void); + +/** + * Frees a tlv_extra structure. + * @param extra Pointer to the structure to free. + */ +void tlv_extra_recycle(struct tlv_extra *extra); + /** * Converts recognized value sub-fields into host byte order. * @param tlv Pointer to a Type Length Value field.