Commit 5198980f authored by Marek Vavrusa's avatar Marek Vavrusa

Initial implementation of atomic reference counting.

GCC builtins are used for atomic add/sub and fetch.
May be extended with assembly for other compilers later.

Commit refs #993.
parent 3d871602
......@@ -40,6 +40,8 @@ src/common/sockaddr.h
src/common/sockaddr.c
src/common/crc.c
src/common/crc.h
src/common/ref.c
src/common/ref.h
src/dnslib/dnslib-common.h
src/dnslib/dname.h
src/dnslib/dname.c
......
......@@ -151,6 +151,8 @@ libknot_la_SOURCES = \
common/sockaddr.c \
common/crc.h \
common/crc.c \
common/ref.h \
common/ref.c \
knot/stat/gatherer.c \
knot/stat/stat.c \
knot/stat/gatherer.h \
......
#include <stdio.h>
#include "ref.h"
void ref_init(ref_t *p, ref_destructor_t dtor)
{
p->count = 0;
p->dtor = dtor;
}
void ref_retain(ref_t *p)
{
__sync_add_and_fetch(&p->count, 1);
}
void ref_release(ref_t *p)
{
if (__sync_sub_and_fetch(&p->count, 1) <= 0) {
p->dtor(p);
}
}
/*!
* \file ref.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
* \brief Atomic reference counting structures.
*
* Reference counting allows implicit sharing of objects
* between threads with custom destructor functions.
*
* \addtogroup common_lib
* @{
*/
#ifndef _KNOT_REF_H_
#define _KNOT_REF_H_
#include <stddef.h>
struct ref_t;
/*! \brief Prototype for object destructor callback. */
typedef void (*ref_destructor_t)(struct ref_t * p);
/*!
* \brief Structure for reference counting.
*
* Size equals to two sizes of pointer size.
* Structure may be embedded to the structures which
* we want to use for reference counting.
*
* \code
* struct mystruct {
* ref_t ref;
* int mydata;
* char *mystr;
* }
* \endcode
*/
typedef struct ref_t {
size_t count; /*! \brief Reference counter. */
ref_destructor_t dtor; /*! \brief Object destructor function. */
} ref_t;
/*!
* \brief Initialize reference counter.
*
* Set reference counter to 0 and initialize destructor callback.
*
* \param p Reference-counted object.
* \param dtor Destructor function.
*/
void ref_init(ref_t *p, ref_destructor_t dtor);
/*!
* \brief Mark object as used by the caller.
*
* Reference counter will be incremented.
*
* \param p Reference-counted object.
*/
void ref_retain(ref_t *p);
/*!
* \brief Marks object as unused by the caller.
*
* Reference counter will be decremented.
*
* \param p Reference-counted object.
*/
void ref_release(ref_t *p);
#endif /* _KNOT_REF_H_ */
/*! @} */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment