Skip to content

Commit

Permalink
Implement simplified (fast) version of the refcounter class.
Browse files Browse the repository at this point in the history
  • Loading branch information
sobomax committed Jul 10, 2023
1 parent 27060f7 commit 6b0685e
Show file tree
Hide file tree
Showing 17 changed files with 236 additions and 97 deletions.
17 changes: 14 additions & 3 deletions src/genfincode.sub
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ emit_fintestfunction() {
echo " } *tp;"
echo ""
echo " naborts_s = _naborts;"
echo " tp = rtpp_rzmalloc(sizeof(*tp), offsetof(typeof(*tp), pub.rcnt));"
if [ "${oname}" != "rtpp_refcnt_fast" ]
then
echo " tp = rtpp_rzmalloc(sizeof(*tp), offsetof(typeof(*tp), pub.rcnt));"
else
echo " tp = rtpp_rgmalloc(MLT_RF, MLT_ZR, sizeof(*tp), offsetof(typeof(*tp), pub.rcnt));"
fi
echo " assert(tp != NULL);"
echo " assert(tp->pub.rcnt != NULL);"
if [ ${static} -ne 0 ]
Expand All @@ -98,8 +103,14 @@ emit_fintestfunction() {
echo " };"
echo " tp->pub.smethods = &dummy;"
fi
echo " CALL_SMETHOD(tp->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&${oname}_fin,"
echo " &tp->pub);"
if [ "${oname}" != "rtpp_refcnt_fast" ]
then
echo " CALL_SMETHOD(tp->pub.rcnt, attach, (rtpp_refcnt_dtor_t)&${oname}_fin,"
echo " &tp->pub);"
else
echo " CALL_SMETHOD(tp->pub.rcnt, attach, USE_DTOR(${oname}_fin,"
echo " &tp->pub));"
fi
echo " RTPP_OBJ_DECREF(&(tp->pub));"
i=0
for mname in ${mnames}
Expand Down
4 changes: 2 additions & 2 deletions src/rtp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ rtp_packet_alloc()
{
struct rtp_packet_full *pkt;

pkt = rtpp_rzmalloc(sizeof(*pkt), PVT_RCOFFS(pkt));
pkt = rtpp_rgmalloc(MLT_RF, MLT_ZR, sizeof(*pkt), PVT_RCOFFS(pkt));
if (pkt == NULL) {
return (NULL);
}
CALL_SMETHOD(pkt->pub.rcnt, use_stdfree, pkt);
CALL_SMETHOD(pkt->pub.rcnt, attach, USE_STDFREE(pkt));
pkt->pub.wi = &(pkt->pvt.wip.pub);

return &(pkt->pub);
Expand Down
4 changes: 2 additions & 2 deletions src/rtp_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@

struct rtp_info;
struct rtpp_wi;
struct rtpp_refcnt;
struct rtpp_refcnt_fast;
struct sthread_args;
struct packet_processor_if;

#define MAX_RPKT_LEN 8192

struct rtp_packet {
struct rtpp_refcnt *rcnt;
struct rtpp_refcnt_fast *rcnt;
#if defined(_RTP_H_)
struct rtpp_wi *wi;
struct rtp_packet *next;
Expand Down
76 changes: 23 additions & 53 deletions src/rtpp_mallocs.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,27 @@ struct alig_help {

void *
#if !defined(RTPP_CHECK_LEAKS)
rtpp_rzmalloc(size_t msize, size_t rcntp_offs)
rtpp_rgmalloc(enum rtpp_ml_reftype rt, enum rtpp_ml_zflag zf, size_t msize,
size_t rcntp_offs)
#else
rtpp_rzmalloc_memdeb(size_t msize, size_t rcntp_offs, void *memdeb_p,
rtpp_rgmalloc_memdeb(enum rtpp_ml_reftype rt, enum rtpp_ml_zflag zf,
size_t msize, size_t rcntp_offs, void *memdeb_p,
const struct rtpp_codeptr *mlp)
#endif
{
void *rval;
struct rtpp_refcnt *rcnt;
size_t pad_size, asize;
union {
struct rtpp_refcnt *norm;
struct rtpp_refcnt_fast *fast;
} rcnt;
size_t pad_size, asize, rosize;
void *rco;

RTPP_DBG_ASSERT(msize >= rcntp_offs + sizeof(struct rtpp_refcnt *));
if (offsetof(struct alig_help, b) > 1) {
pad_size = msize % offsetof(struct alig_help, b);
if (pad_size != 0) {
pad_size = offsetof(struct alig_help, b) - pad_size;
}
} else {
pad_size = 0;
}
asize = msize + pad_size + rtpp_refcnt_osize();
size_t norm_off = offsetof(struct alig_help, b);
pad_size = (norm_off - msize) & (norm_off - 1);
rosize = (rt != MLT_RF) ? rtpp_refcnt_osize() : rtpp_refcnt_fast_osize;
asize = msize + pad_size + rosize;
#if !defined(RTPP_CHECK_LEAKS)
rval = malloc(asize);
#else
Expand All @@ -95,49 +95,19 @@ rtpp_rzmalloc_memdeb(size_t msize, size_t rcntp_offs, void *memdeb_p,
if (rval == NULL) {
return (NULL);
}
memset(rval, '\0', asize);
if (zf == MLT_ZR) {
memset(rval, '\0', asize);
}
rco = (char *)rval + msize + pad_size;
rcnt = rtpp_refcnt_ctor_pa(rco);
*PpP(rval, rcntp_offs, struct rtpp_refcnt **) = rcnt;

return (rval);
}

void *
#if !defined(RTPP_CHECK_LEAKS)
rtpp_rmalloc(size_t msize, size_t rcntp_offs)
#else
rtpp_rmalloc_memdeb(size_t msize, size_t rcntp_offs, void *memdeb_p,
const struct rtpp_codeptr *mlp)
#endif
{
void *rval;
struct rtpp_refcnt *rcnt;
size_t pad_size, asize;
void *rco;

RTPP_DBG_ASSERT(msize >= rcntp_offs + sizeof(struct rtpp_refcnt *));
if (offsetof(struct alig_help, b) > 1) {
pad_size = msize % offsetof(struct alig_help, b);
if (pad_size != 0) {
pad_size = offsetof(struct alig_help, b) - pad_size;
}
} else {
pad_size = 0;
if (zf != MLT_ZR) {
memset(rco, '\0', rosize);
}
asize = msize + pad_size + rtpp_refcnt_osize();
#if !defined(RTPP_CHECK_LEAKS)
rval = malloc(asize);
#else
rval = rtpp_memdeb_malloc(asize, memdeb_p, mlp);
#endif
if (rval == NULL) {
return (NULL);
if (rt != MLT_RF) {
rcnt.norm = rtpp_refcnt_ctor_pa(rco);
} else {
rcnt.fast = rtpp_refcnt_fast_ctor(rco);
}
rco = (char *)rval + msize + pad_size;
memset(rco, '\0', rtpp_refcnt_osize());
rcnt = rtpp_refcnt_ctor_pa(rco);
*PpP(rval, rcntp_offs, struct rtpp_refcnt **) = rcnt;
*PpP(rval, rcntp_offs, struct rtpp_refcnt **) = rcnt.norm;

return (rval);
}
30 changes: 16 additions & 14 deletions src/rtpp_mallocs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,28 @@
#ifndef _RTPP_MALLOCS_H_
#define _RTPP_MALLOCS_H_

enum rtpp_ml_reftype {MLT_R, MLT_RF};
enum rtpp_ml_zflag {MLT_NZ, MLT_ZR};

/* Function prototypes */
#if defined(RTPP_CHECK_LEAKS)
void *rtpp_rgmalloc_memdeb(enum rtpp_ml_reftype, enum rtpp_ml_zflag, size_t, size_t, void *, HERETYPE);
static inline void *rtpp_rzmalloc_memdeb(size_t msize, size_t rcntp_offs, void *memdeb_p,
const struct rtpp_codeptr *mlp) {return(rtpp_rgmalloc_memdeb(MLT_R, MLT_ZR, msize, rcntp_offs,
memdeb_p, mlp));}

#define rtpp_zmalloc(s) rtpp_zmalloc_memdeb((s), MEMDEB_SYM, HEREVAL)
#define rtpp_rzmalloc(x, y) rtpp_rgmalloc_memdeb(MLT_R, MLT_ZR, x, y, MEMDEB_SYM, HEREVAL)
#define rtpp_rmalloc(x, y) rtpp_rgmalloc_memdeb(MLT_R, MLT_NZ, x, y, MEMDEB_SYM, HEREVAL)
#define rtpp_rgmalloc(a, b, x, y) rtpp_rgmalloc_memdeb(a, b, x, y, MEMDEB_SYM, HEREVAL)
void *rtpp_zmalloc_memdeb(size_t, void *, HERETYPE);
#else
void *rtpp_zmalloc(size_t);
#endif
void *rtpp_rgmalloc(enum rtpp_ml_reftype, enum rtpp_ml_zflag, size_t, size_t);
static inline void *rtpp_rzmalloc(size_t a, size_t b) {return(rtpp_rgmalloc(MLT_R, MLT_ZR, a, b));}

#if defined(RTPP_CHECK_LEAKS)
#define rtpp_rzmalloc(x, y) rtpp_rzmalloc_memdeb(x, y, MEMDEB_SYM, HEREVAL)
void *rtpp_rzmalloc_memdeb(size_t, size_t, void *, HERETYPE);
#else
void *rtpp_rzmalloc(size_t, size_t);
#endif

#if defined(RTPP_CHECK_LEAKS)
#define rtpp_rmalloc(x, y) rtpp_rmalloc_memdeb(x, y, MEMDEB_SYM, HEREVAL)
void *rtpp_rmalloc_memdeb(size_t, size_t, void *, HERETYPE);
#else
void *rtpp_rmalloc(size_t, size_t);
#define rtpp_rzmalloc(x, y) rtpp_rgmalloc(MLT_R, MLT_ZR, x, y)
#define rtpp_rmalloc(x, y) rtpp_rgmalloc(MLT_R, MLT_NZ, x, y)
void *rtpp_zmalloc(size_t);
#endif

#endif
2 changes: 1 addition & 1 deletion src/rtpp_netio_async.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@
#include "rtpp_time.h"
#include "rtp_packet.h"
#include "rtpp_types.h"
#include "rtpp_refcnt.h"
#include "rtpp_wi.h"
#include "rtpp_wi_pkt.h"
#include "rtpp_wi_sgnl.h"
#include "rtpp_wi_private.h"
#include "rtpp_refcnt.h"
#include "rtpp_log_obj.h"
#include "rtpp_queue.h"
#include "rtpp_network.h"
Expand Down
85 changes: 82 additions & 3 deletions src/rtpp_refcnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "rtpp_types.h"
#include "rtpp_mallocs.h"
#include "rtpp_refcnt.h"
#include "rtpp_util.h"
#include "rtpp_refcnt_fin.h"

#if RTPP_DEBUG_refcnt
Expand All @@ -50,9 +51,6 @@
#endif
#endif

static void rtpp_refcnt_incref(struct rtpp_refcnt *);
static void rtpp_refcnt_decref(struct rtpp_refcnt *);

/*
* Somewhat arbitrary cap on the maximum value of the references. Just here
* to catch any runaway situations, i.e. bugs in the code.
Expand All @@ -76,6 +74,8 @@ struct rtpp_refcnt_priv
int flags;
};

static void rtpp_refcnt_incref(struct rtpp_refcnt *);
static void rtpp_refcnt_decref(struct rtpp_refcnt *);
static void rtpp_refcnt_attach(struct rtpp_refcnt *, rtpp_refcnt_dtor_t,
void *);
static void *rtpp_refcnt_getdata(struct rtpp_refcnt *);
Expand Down Expand Up @@ -297,3 +297,82 @@ rtpp_refcnt_use_stdfree(struct rtpp_refcnt *pub, void *data)
pvt->flags |= RC_FLAG_PA_STDFREE;
pvt->data = data;
}

struct rtpp_refcnt_fast_priv
{
struct rtpp_refcnt_fast pub;
atomic_long cnt;
refcnt_dtorspec_t dspec;
};
const size_t rtpp_refcnt_fast_osize = sizeof(struct rtpp_refcnt_fast_priv);

static void rtpp_refcnt_fast_incref(rtpp_refcnt_fast_rot *);
static void rtpp_refcnt_fast_decref(rtpp_refcnt_fast_rot *);
static refcnt_dtorspec_t rtpp_refcnt_fast_attach(rtpp_refcnt_fast_rot *,
const refcnt_dtorspec_t *);

DEFINE_SMETHODS(rtpp_refcnt_fast,
.incref = &rtpp_refcnt_fast_incref,
.decref = &rtpp_refcnt_fast_decref,
.attach = &rtpp_refcnt_fast_attach,
);

struct rtpp_refcnt_fast *
rtpp_refcnt_fast_ctor(void *pap)
{
struct rtpp_refcnt_fast_priv *pvt;

pvt = (struct rtpp_refcnt_fast_priv *)pap;
#if defined(RTPP_DEBUG)
pvt->pub.smethods = rtpp_refcnt_fast_smethods;
#endif
atomic_init(&pvt->cnt, 1);
return (&pvt->pub);
}

static void
rtpp_refcnt_fast_incref(struct rtpp_refcnt_fast *pub)
{
struct rtpp_refcnt_fast_priv *pvt;

PUB2PVT(pub, pvt);
RTPP_DBG_ASSERT(((uintptr_t)&pvt->cnt & 0b111) == 0 && atomic_load(&pvt->cnt) > 0 && atomic_load(&pvt->cnt) < RC_ABS_MAX);
atomic_fetch_add_explicit(&pvt->cnt, 1, memory_order_relaxed);
}

static void
rtpp_refcnt_fast_decref(struct rtpp_refcnt_fast *pub)
{
struct rtpp_refcnt_fast_priv *pvt;
int oldcnt;

PUB2PVT(pub, pvt);
RTPP_DBG_ASSERT(((uintptr_t)&pvt->cnt & 0b111) == 0);
oldcnt = atomic_fetch_sub_explicit(&pvt->cnt, 1, memory_order_release);
if (likely(oldcnt > 1))
return;
atomic_thread_fence(memory_order_acquire);
pvt->dspec.dtor(pvt->dspec.ptr);
return;
}

static refcnt_dtorspec_t
rtpp_refcnt_fast_attach(struct rtpp_refcnt_fast *pub, const refcnt_dtorspec_t *dsp)
{
struct rtpp_refcnt_fast_priv *pvt;
refcnt_dtorspec_t old;

PUB2PVT(pub, pvt);
old = pvt->dspec;
pvt->dspec.ptr = dsp->ptr;
if (dsp->dtor == DTOR_STDFREE) {
#if !defined(RTPP_CHECK_LEAKS)
pvt->dspec.dtor = free;
#else
pvt->dspec.dtor = rtpp_refcnt_free;
#endif
} else {
pvt->dspec.dtor = dsp->dtor;
}
return (old);
}
38 changes: 38 additions & 0 deletions src/rtpp_refcnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,41 @@ rtpp_refcnt_rot *rtpp_refcnt_ctor_pa(void *);

#define RC_INCREF(rp) CALL_SMETHOD(rp, incref);
#define RC_DECREF(rp) CALL_SMETHOD(rp, decref);

DECLARE_CLASS(rtpp_refcnt_fast, void *);

extern const size_t rtpp_refcnt_fast_osize;

#define DTOR_STDFREE ((rtpp_refcnt_dtor_t)(void *)(-1))
#define USE_STDFREE(p) (&(refcnt_dtorspec_t){.dtor = DTOR_STDFREE, .ptr = (p)})
#define USE_DTOR(dtr, p) (&(refcnt_dtorspec_t){.dtor = (rtpp_refcnt_dtor_t)(dtr), .ptr = (p)})

struct refcnt_dtorspec {
rtpp_refcnt_dtor_t dtor;
void *ptr;
};
typedef struct refcnt_dtorspec refcnt_dtorspec_t;

DECLARE_METHOD(rtpp_refcnt_fast, refcnt_fast_incref, void);
DECLARE_METHOD(rtpp_refcnt_fast, refcnt_fast_decref, void);
DECLARE_METHOD(rtpp_refcnt_fast, refcnt_fast_getdata, void *);
DECLARE_METHOD(rtpp_refcnt_fast, refcnt_fast_attach, refcnt_dtorspec_t,
const refcnt_dtorspec_t *);

DECLARE_SMETHODS(rtpp_refcnt_fast)
{
METHOD_ENTRY(refcnt_fast_incref, incref);
METHOD_ENTRY(refcnt_fast_decref, decref);
METHOD_ENTRY(refcnt_fast_getdata, getdata);
METHOD_ENTRY(refcnt_fast_attach, attach);
};

struct rtpp_refcnt_fast
{
#if defined(RTPP_FINTEST)
struct rtpp_refcnt_fast *rcnt;
#endif
#if defined(RTPP_DEBUG)
const struct rtpp_refcnt_fast_smethods * smethods;
#endif
};
Loading

0 comments on commit 6b0685e

Please sign in to comment.