From 69f5bf408b9587a6e2008fba2224c2d506f1a895 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 27 Aug 2019 16:13:07 +0200 Subject: [SERVER] Use reference counting for uplink First step towards less locking for proxy mode --- src/server/reference.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/server/reference.c (limited to 'src/server/reference.c') diff --git a/src/server/reference.c b/src/server/reference.c new file mode 100644 index 0000000..468e00b --- /dev/null +++ b/src/server/reference.c @@ -0,0 +1,33 @@ +#ifndef unlikely +#define unlikely(x) (x) +#endif +#include "reference.h" +#include +#include + +void ref_init( ref *reference, void ( *freefun )( ref * ), long count ) +{ + reference->count = count; + reference->free = freefun; +} + +_Noreturn void _ref_error( const char *message ) +{ + fprintf( stderr, "Reference counter overflow\n" ); + abort(); +} + +void ref_setref( weakref *weakref, ref *ref ) +{ + union _aligned_ref_ *new_weakref = 0; + if ( ref ) { + ( new_weakref = aligned_ref( ref->_aligned_ref ) )->ref = ref; + ref->count += sizeof( union _aligned_ref_ ) + 1; + } + char *old_weakref = (char *)atomic_exchange( weakref, new_weakref ); + if ( !old_weakref ) + return; + struct _ref_ *old_ref = aligned_ref( old_weakref )->ref; + old_ref->count += old_weakref - (char *)aligned_ref( old_weakref ) - sizeof( union _aligned_ref_ ); + ref_put( old_ref ); +} -- cgit v1.2.3-55-g7522 From 291eba00d392e17925576ead20b781d774e68134 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 29 Aug 2019 14:48:58 +0200 Subject: [SERVER] reference: Fix error msg usage --- src/server/reference.c | 2 +- src/server/reference.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server/reference.c') diff --git a/src/server/reference.c b/src/server/reference.c index 468e00b..64109ca 100644 --- a/src/server/reference.c +++ b/src/server/reference.c @@ -13,7 +13,7 @@ void ref_init( ref *reference, void ( *freefun )( ref * ), long count ) _Noreturn void _ref_error( const char *message ) { - fprintf( stderr, "Reference counter overflow\n" ); + fprintf( stderr, "%s\n", message ); abort(); } diff --git a/src/server/reference.h b/src/server/reference.h index 0bc081a..8883eb1 100644 --- a/src/server/reference.h +++ b/src/server/reference.h @@ -27,7 +27,7 @@ static inline ref *ref_get( weakref *weakref ) } while ( !atomic_compare_exchange_weak( weakref, (void **)&old_weakref, old_weakref + 1 ) ); struct _ref_ *ref = aligned_ref( old_weakref )->ref; if ( unlikely( ++ref->count == -1 ) ) { - _ref_error( "Reference counter overflow. Aborting.\n" ); + _ref_error( "Reference counter overflow. Aborting." ); } char *cur_weakref = ( char * )*weakref; do { -- cgit v1.2.3-55-g7522