From 200d100e05ed8e10c47f971939042f2406df92ef Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 22 Jun 2016 16:20:25 -0400 Subject: [PATCH] Fix: add missing destroy functions to queues/stack APIs Queues and stack APIs that invoke pthread_mutex_init() should have a "destroy" counterpart which calls pthread_mutex_destroy(), ortherwise this causes small memory leaks on platforms where pthread_mutex_init performs memory allocation. Signed-off-by: Mathieu Desnoyers --- lfstack.c | 5 +++++ urcu/lfstack.h | 13 +++++++++++-- urcu/static/lfstack.h | 17 +++++++++++++++-- urcu/static/wfcqueue.h | 17 +++++++++++++++-- urcu/static/wfqueue.h | 6 ++++++ urcu/static/wfstack.h | 17 +++++++++++++++-- urcu/wfcqueue.h | 14 ++++++++++++-- urcu/wfqueue.h | 9 +++++++++ urcu/wfstack.h | 13 +++++++++++-- wfcqueue.c | 6 ++++++ wfqueue.c | 5 +++++ wfstack.c | 5 +++++ 12 files changed, 115 insertions(+), 12 deletions(-) diff --git a/lfstack.c b/lfstack.c index 3dac178..c974a47 100644 --- a/lfstack.c +++ b/lfstack.c @@ -40,6 +40,11 @@ void cds_lfs_init(struct cds_lfs_stack *s) _cds_lfs_init(s); } +void cds_lfs_destroy(struct cds_lfs_stack *s) +{ + _cds_lfs_destroy(s); +} + void __cds_lfs_init(struct __cds_lfs_stack *s) { ___cds_lfs_init(s); diff --git a/urcu/lfstack.h b/urcu/lfstack.h index 11a63d9..5a9bca3 100644 --- a/urcu/lfstack.h +++ b/urcu/lfstack.h @@ -95,6 +95,7 @@ typedef union { #define cds_lfs_node_init _cds_lfs_node_init #define cds_lfs_init _cds_lfs_init +#define cds_lfs_destroy _cds_lfs_destroy #define __cds_lfs_init ___cds_lfs_init #define cds_lfs_empty _cds_lfs_empty #define cds_lfs_push _cds_lfs_push @@ -119,12 +120,20 @@ typedef union { extern void cds_lfs_node_init(struct cds_lfs_node *node); /* - * cds_lfs_init: initialize lock-free stack. + * cds_lfs_init: initialize lock-free stack (with locking). Pair with + * cds_lfs_destroy(). */ extern void cds_lfs_init(struct cds_lfs_stack *s); /* - * __cds_lfs_init: initialize lock-free stack. + * cds_lfs_destroy: destroy lock-free stack (with lock). Pair with + * cds_lfs_init(). + */ +extern void cds_lfs_destroy(struct cds_lfs_stack *s); + +/* + * __cds_lfs_init: initialize lock-free stack (without lock). + * Don't pair with any destroy function. */ extern void __cds_lfs_init(struct __cds_lfs_stack *s); diff --git a/urcu/static/lfstack.h b/urcu/static/lfstack.h index 7afe71e..05d0bb4 100644 --- a/urcu/static/lfstack.h +++ b/urcu/static/lfstack.h @@ -66,7 +66,8 @@ void _cds_lfs_node_init(struct cds_lfs_node *node) } /* - * cds_lfs_init: initialize lock-free stack. + * cds_lfs_init: initialize lock-free stack (with lock). Pair with + * cds_lfs_destroy(). */ static inline void _cds_lfs_init(struct cds_lfs_stack *s) @@ -79,7 +80,19 @@ void _cds_lfs_init(struct cds_lfs_stack *s) } /* - * ___cds_lfs_init: initialize lock-free stack. + * cds_lfs_destroy: destroy lock-free stack (with lock). Pair with + * cds_lfs_init(). + */ +static inline +void _cds_lfs_destroy(struct cds_lfs_stack *s) +{ + int ret = pthread_mutex_destroy(&s->lock); + assert(!ret); +} + +/* + * ___cds_lfs_init: initialize lock-free stack (without lock). + * Don't pair with any destroy function. */ static inline void ___cds_lfs_init(struct __cds_lfs_stack *s) diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 4ababbf..67ac05f 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -92,7 +92,8 @@ static inline void _cds_wfcq_node_init(struct cds_wfcq_node *node) } /* - * cds_wfcq_init: initialize wait-free queue. + * cds_wfcq_init: initialize wait-free queue (with lock). Pair with + * cds_wfcq_destroy(). */ static inline void _cds_wfcq_init(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) @@ -107,7 +108,19 @@ static inline void _cds_wfcq_init(struct cds_wfcq_head *head, } /* - * __cds_wfcq_init: initialize wait-free queue. + * cds_wfcq_destroy: destroy wait-free queue (with lock). Pair with + * cds_wfcq_init(). + */ +static inline void _cds_wfcq_destroy(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail) +{ + int ret = pthread_mutex_destroy(&head->lock); + assert(!ret); +} + +/* + * __cds_wfcq_init: initialize wait-free queue (without lock). Don't + * pair with any destroy function. */ static inline void ___cds_wfcq_init(struct __cds_wfcq_head *head, struct cds_wfcq_tail *tail) diff --git a/urcu/static/wfqueue.h b/urcu/static/wfqueue.h index cc21fac..df9f62f 100644 --- a/urcu/static/wfqueue.h +++ b/urcu/static/wfqueue.h @@ -65,6 +65,12 @@ static inline void _cds_wfq_init(struct cds_wfq_queue *q) assert(!ret); } +static inline void _cds_wfq_destroy(struct cds_wfq_queue *q) +{ + int ret = pthread_mutex_destroy(&q->lock); + assert(!ret); +} + static inline void _cds_wfq_enqueue(struct cds_wfq_queue *q, struct cds_wfq_node *node) { diff --git a/urcu/static/wfstack.h b/urcu/static/wfstack.h index 2666b0e..e96c887 100644 --- a/urcu/static/wfstack.h +++ b/urcu/static/wfstack.h @@ -77,7 +77,8 @@ void _cds_wfs_node_init(struct cds_wfs_node *node) } /* - * __cds_wfs_init: initialize wait-free stack. + * __cds_wfs_init: initialize wait-free stack. Don't pair with + * any destroy function. */ static inline void ___cds_wfs_init(struct __cds_wfs_stack *s) { @@ -85,7 +86,8 @@ static inline void ___cds_wfs_init(struct __cds_wfs_stack *s) } /* - * cds_wfs_init: initialize wait-free stack. + * cds_wfs_init: initialize wait-free stack. Pair with + * cds_wfs_destroy(). */ static inline void _cds_wfs_init(struct cds_wfs_stack *s) @@ -97,6 +99,17 @@ void _cds_wfs_init(struct cds_wfs_stack *s) assert(!ret); } +/* + * cds_wfs_destroy: destroy wait-free stack. Pair with + * cds_wfs_init(). + */ +static inline +void _cds_wfs_destroy(struct cds_wfs_stack *s) +{ + int ret = pthread_mutex_destroy(&s->lock); + assert(!ret); +} + static inline bool ___cds_wfs_end(void *node) { return node == CDS_WFS_END; diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h index c65780e..6c6ebba 100644 --- a/urcu/wfcqueue.h +++ b/urcu/wfcqueue.h @@ -135,6 +135,7 @@ struct cds_wfcq_tail { #define cds_wfcq_node_init _cds_wfcq_node_init #define cds_wfcq_init _cds_wfcq_init #define __cds_wfcq_init ___cds_wfcq_init +#define cds_wfcq_destroy _cds_wfcq_destroy #define cds_wfcq_empty _cds_wfcq_empty #define cds_wfcq_enqueue _cds_wfcq_enqueue @@ -213,13 +214,22 @@ struct cds_wfcq_tail { extern void cds_wfcq_node_init(struct cds_wfcq_node *node); /* - * cds_wfcq_init: initialize wait-free queue. + * cds_wfcq_init: initialize wait-free queue. Pair with + * cds_wfcq_destroy(). */ extern void cds_wfcq_init(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail); /* - * __cds_wfcq_init: initialize wait-free queue. + * cds_wfcq_destroy: destroy wait-free queue. Pair with + * cds_wfcq_init(). + */ +extern void cds_wfcq_destroy(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail); + +/* + * __cds_wfcq_init: initialize wait-free queue (without lock). Don't + * pair with any destroy function. */ extern void __cds_wfcq_init(struct __cds_wfcq_head *head, struct cds_wfcq_tail *tail); diff --git a/urcu/wfqueue.h b/urcu/wfqueue.h index 4cd4b13..2ba8624 100644 --- a/urcu/wfqueue.h +++ b/urcu/wfqueue.h @@ -71,6 +71,12 @@ void cds_wfq_init(struct cds_wfq_queue *q) _cds_wfq_init(q); } +static inline CDS_WFQ_DEPRECATED +void cds_wfq_destroy(struct cds_wfq_queue *q) +{ + _cds_wfq_destroy(q); +} + static inline CDS_WFQ_DEPRECATED void cds_wfq_enqueue(struct cds_wfq_queue *q, struct cds_wfq_node *node) { @@ -97,6 +103,9 @@ void cds_wfq_node_init(struct cds_wfq_node *node); extern CDS_WFQ_DEPRECATED void cds_wfq_init(struct cds_wfq_queue *q); +extern CDS_WFQ_DEPRECATED +void cds_wfq_destroy(struct cds_wfq_queue *q); + extern CDS_WFQ_DEPRECATED void cds_wfq_enqueue(struct cds_wfq_queue *q, struct cds_wfq_node *node); diff --git a/urcu/wfstack.h b/urcu/wfstack.h index 28f6162..9d69305 100644 --- a/urcu/wfstack.h +++ b/urcu/wfstack.h @@ -108,6 +108,7 @@ typedef union { #define cds_wfs_node_init _cds_wfs_node_init #define cds_wfs_init _cds_wfs_init +#define cds_wfs_destroy _cds_wfs_destroy #define __cds_wfs_init ___cds_wfs_init #define cds_wfs_empty _cds_wfs_empty #define cds_wfs_push _cds_wfs_push @@ -146,12 +147,20 @@ typedef union { extern void cds_wfs_node_init(struct cds_wfs_node *node); /* - * cds_wfs_init: initialize wait-free stack. + * cds_wfs_init: initialize wait-free stack (with lock). Pair with + * cds_wfs_destroy(). */ extern void cds_wfs_init(struct cds_wfs_stack *s); /* - * __cds_wfs_init: initialize wait-free stack. + * cds_wfs_destroy: destroy wait-free stack (with lock). Pair with + * cds_wfs_init(). + */ +extern void cds_wfs_destroy(struct cds_wfs_stack *s); + +/* + * __cds_wfs_init: initialize wait-free stack (no lock). Don't pair with + * any destroy function. */ extern void __cds_wfs_init(struct __cds_wfs_stack *s); diff --git a/wfcqueue.c b/wfcqueue.c index e28d51a..85de8ec 100644 --- a/wfcqueue.c +++ b/wfcqueue.c @@ -40,6 +40,12 @@ void cds_wfcq_init(struct cds_wfcq_head *head, _cds_wfcq_init(head, tail); } +void cds_wfcq_destroy(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail) +{ + _cds_wfcq_destroy(head, tail); +} + void __cds_wfcq_init(struct __cds_wfcq_head *head, struct cds_wfcq_tail *tail) { diff --git a/wfqueue.c b/wfqueue.c index 14272cb..509f4f9 100644 --- a/wfqueue.c +++ b/wfqueue.c @@ -41,6 +41,11 @@ void cds_wfq_init(struct cds_wfq_queue *q) _cds_wfq_init(q); } +void cds_wfq_destroy(struct cds_wfq_queue *q) +{ + _cds_wfq_destroy(q); +} + void cds_wfq_enqueue(struct cds_wfq_queue *q, struct cds_wfq_node *node) { _cds_wfq_enqueue(q, node); diff --git a/wfstack.c b/wfstack.c index 7618be3..46300f9 100644 --- a/wfstack.c +++ b/wfstack.c @@ -38,6 +38,11 @@ void cds_wfs_init(struct cds_wfs_stack *s) _cds_wfs_init(s); } +void cds_wfs_destroy(struct cds_wfs_stack *s) +{ + _cds_wfs_destroy(s); +} + void __cds_wfs_init(struct __cds_wfs_stack *s) { ___cds_wfs_init(s); -- 2.34.1