Skip to content

Commit

Permalink
util, spad: handholding overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
ravyu-jump committed Jan 10, 2025
1 parent 99d5622 commit ad21efc
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 59 deletions.
1 change: 1 addition & 0 deletions config/extra/with-handholding.mk
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ CPPFLAGS+=-DFD_EQVOC_USE_HANDHOLDING=1
CPPFLAGS+=-DFD_FORKS_USE_HANDHOLDING=1
CPPFLAGS+=-DFD_GHOST_USE_HANDHOLDING=1
CPPFLAGS+=-DFD_SCRATCH_USE_HANDHOLDING=1
CPPFLAGS+=-DFD_SPAD_USE_HANDHOLDING=1
CPPFLAGS+=-DFD_TOWER_USE_HANDHOLDING=1
# CPPFLAGS+=-DFD_TXN_HANDHOLDING=1 # FIXME: Compile errors
26 changes: 11 additions & 15 deletions src/util/spad/fd_spad.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,31 @@ fd_spad_alloc_max_debug( fd_spad_t const * spad,
ulong align ) {
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
if( FD_UNLIKELY( (!!align) & (!fd_ulong_is_pow2( align ) ) ) ) FD_LOG_CRIT(( "bad align" ));
return fd_spad_alloc_max( spad, align );
return fd_spad_alloc_max_impl( spad, align );
}

void *
fd_spad_frame_lo_debug( fd_spad_t * spad ) {
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
return fd_spad_frame_lo( spad );
return fd_spad_frame_lo_impl( spad );
}

void *
fd_spad_frame_hi_debug( fd_spad_t * spad ) {
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
return fd_spad_frame_hi( spad );
return fd_spad_frame_hi_impl( spad );
}

void
fd_spad_push_debug( fd_spad_t * spad ) {
if( FD_UNLIKELY( !fd_spad_frame_free( spad ) ) ) FD_LOG_CRIT(( "too many frames" ));
fd_spad_push( spad );
fd_spad_push_impl( spad );
}

void
fd_spad_pop_debug( fd_spad_t * spad ) {
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
fd_spad_pop( spad );
fd_spad_pop_impl( spad );
}

void *
Expand All @@ -71,7 +71,7 @@ fd_spad_alloc_debug( fd_spad_t * spad,
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
if( FD_UNLIKELY( (!!align) & (!fd_ulong_is_pow2( align ) ) ) ) FD_LOG_CRIT(( "bad align" ));
if( FD_UNLIKELY( fd_spad_alloc_max( spad, align )<sz ) ) FD_LOG_CRIT(( "bad sz" ));
return fd_spad_alloc( spad, align, sz );
return fd_spad_alloc_impl( spad, align, sz );
}

void
Expand All @@ -80,7 +80,7 @@ fd_spad_trim_debug( fd_spad_t * spad,
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
if( FD_UNLIKELY( ((ulong)fd_spad_frame_lo( spad ))>(ulong)hi ) ) FD_LOG_CRIT(( "hi below frame_lo" ));
if( FD_UNLIKELY( ((ulong)fd_spad_frame_hi( spad ))<(ulong)hi ) ) FD_LOG_CRIT(( "hi above frame_hi" ));
fd_spad_trim( spad, hi );
fd_spad_trim_impl( spad, hi );
}

void *
Expand All @@ -90,15 +90,15 @@ fd_spad_prepare_debug( fd_spad_t * spad,
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
if( FD_UNLIKELY( (!!align) & (!fd_ulong_is_pow2( align ) ) ) ) FD_LOG_CRIT(( "bad align" ));
if( FD_UNLIKELY( fd_spad_alloc_max( spad, align )<max ) ) FD_LOG_CRIT(( "bad max" ));
return fd_spad_prepare( spad, align, max );
return fd_spad_prepare_impl( spad, align, max );
}

void
fd_spad_cancel_debug( fd_spad_t * spad ) {
if( FD_UNLIKELY( !fd_spad_frame_used( spad ) ) ) FD_LOG_CRIT(( "not in a frame" ));
/* FIXME: check if in prepare? needs extra state and a lot of extra
tracking that state */
fd_spad_cancel( spad );
fd_spad_cancel_impl( spad );
}

void
Expand All @@ -108,7 +108,7 @@ fd_spad_publish_debug( fd_spad_t * spad,
if( FD_UNLIKELY( fd_spad_alloc_max( spad, 1UL )<sz ) ) FD_LOG_CRIT(( "bad sz" ));
/* FIXME: check if in prepare? needs extra state and a lot of extra
tracking that state */
fd_spad_publish( spad, sz );
fd_spad_publish_impl( spad, sz );
}

/* fd_valloc virtual function table for spad */
Expand All @@ -117,11 +117,7 @@ fd_spad_valloc_malloc( void * _self,
ulong align,
ulong sz ) {
fd_spad_t * spad = _self;
void * rv = fd_spad_alloc( spad, align, sz );
if( FD_UNLIKELY( fd_spad_mem_used( spad )>fd_spad_mem_max( spad ) ) ) {
FD_LOG_ERR(( "spad overflow mem_used=%lu mem_max=%lu", fd_spad_mem_used( spad ), fd_spad_mem_max( spad ) ));
}
return rv;
return fd_spad_alloc( spad, align, sz );
}

static void
Expand Down
202 changes: 158 additions & 44 deletions src/util/spad/fd_spad.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ FD_FN_PURE static inline ulong fd_spad_mem_free( fd_spad_t const * spad ) { retu

FD_FN_PURE static inline int fd_spad_in_frame( fd_spad_t const * spad ) { return spad->frame_free<FD_SPAD_FRAME_MAX; }


/* operations */
/* fd_spad_alloc_max returns the maximum number of bytes with initial
byte alignment of align that can currently be allocated / prepared
(not including any in-progress prepare). Assumes spad is a current
Expand All @@ -294,11 +296,7 @@ FD_FN_PURE static inline int fd_spad_in_frame( fd_spad_t const * spad ) { return

FD_FN_PURE static inline ulong
fd_spad_alloc_max( fd_spad_t const * spad,
ulong align ) {
align = fd_ulong_if( align>0UL, align, FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
ulong off = fd_ulong_align_up( spad->mem_used, align );
return fd_ulong_max( spad->mem_max, off ) - off;
}
ulong align );

/* fd_spad_frame_{lo,hi} returns the range of spad memory covered by the
current frame (not including any in-progress prepare). That is,
Expand All @@ -307,14 +305,10 @@ fd_spad_alloc_max( fd_spad_t const * spad,
FIXME: consider const correct versions? */

FD_FN_PURE static inline void *
fd_spad_frame_lo( fd_spad_t * spad ) {
return fd_spad_private_mem( spad ) + spad->off[ spad->frame_free ];
}
fd_spad_frame_lo( fd_spad_t * spad );

FD_FN_PURE static inline void *
fd_spad_frame_hi( fd_spad_t * spad ) {
return fd_spad_private_mem( spad ) + spad->mem_used;
}
fd_spad_frame_hi( fd_spad_t * spad );

/* operations */

Expand All @@ -324,9 +318,7 @@ fd_spad_frame_hi( fd_spad_t * spad ) {
in a frame and not in a prepare. Fast O(1). */

static inline void
fd_spad_push( fd_spad_t * spad ) {
spad->off[ --spad->frame_free ] = spad->mem_used;
}
fd_spad_push( fd_spad_t * spad );

/* fd_spad_pop destroys the current spad frame (which bulk frees all
allocations made in that frame and cancels any in progress prepare)
Expand All @@ -336,9 +328,7 @@ fd_spad_push( fd_spad_t * spad ) {
and not otherwise. Fast O(1). */

static inline void
fd_spad_pop( fd_spad_t * spad ) {
spad->mem_used = spad->off[ spad->frame_free++ ];
}
fd_spad_pop( fd_spad_t * spad );

/* The construct:
Expand All @@ -358,9 +348,7 @@ fd_spad_pop( fd_spad_t * spad ) {
is entered. Fast O(1). */

static inline void
fd_spad_private_frame_end( fd_spad_t ** _spad ) { /* declared here to avoid a fd_spad_pop forward reference */
fd_spad_pop( *_spad );
}
fd_spad_private_frame_end( fd_spad_t ** _spad ); /* declared here to avoid a fd_spad_pop forward reference */

#define FD_SPAD_FRAME_BEGIN(spad) do { \
fd_spad_t * _spad __attribute__((cleanup(fd_spad_private_frame_end))) = (spad); \
Expand All @@ -387,13 +375,7 @@ fd_spad_private_frame_end( fd_spad_t ** _spad ) { /* declared here to avoid a fd
static inline void *
fd_spad_alloc( fd_spad_t * spad,
ulong align,
ulong sz ) {
align = fd_ulong_if( align>0UL, align, FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
ulong off = fd_ulong_align_up( spad->mem_used, align );
uchar * buf = fd_spad_private_mem( spad ) + off;
spad->mem_used = off + sz;
return buf;
}
ulong sz );

/* fd_spad_trim trims trims frame_hi to end at hi where hi is given the
caller's local address space. Assumes spad is a current local join
Expand All @@ -416,9 +398,7 @@ fd_spad_alloc( fd_spad_t * spad,

static inline void
fd_spad_trim( fd_spad_t * spad,
void * hi ) {
spad->mem_used = (ulong)hi - (ulong)fd_spad_private_mem( spad );
}
void * hi );

/* fd_spad_prepare starts preparing a spad allocation with alignment
align that can be up to max bytes in size. Returns a pointer in the
Expand Down Expand Up @@ -451,14 +431,7 @@ fd_spad_trim( fd_spad_t * spad,
static inline void *
fd_spad_prepare( fd_spad_t * spad,
ulong align,
ulong max ) {
(void)max;
align = fd_ulong_if( align>0UL, align, FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
ulong off = fd_ulong_align_up( spad->mem_used, align );
uchar * buf = fd_spad_private_mem( spad ) + off;
spad->mem_used = off;
return buf;
}
ulong max );

/* fd_spad_cancel cancels the most recent prepare. Assumes spad is a
current local join and in a prepare. On return, spad will be in a
Expand All @@ -478,9 +451,7 @@ fd_spad_prepare( fd_spad_t * spad,
described above. So this probably isn't worthwhile. */

static inline void
fd_spad_cancel( fd_spad_t * spad ) {
(void)spad;
}
fd_spad_cancel( fd_spad_t * spad );

/* fd_spad_publish finishes the allocation started in the most recent
prepare. Assumes spad is a current local join and in a prepare and
Expand All @@ -489,9 +460,7 @@ fd_spad_cancel( fd_spad_t * spad ) {

static inline void
fd_spad_publish( fd_spad_t * spad,
ulong sz ) {
spad->mem_used += sz;
}
ulong sz );

/* fd_spad_verify returns a negative integer error code if the spad is
obiviously corrupt if not (logs details) and 0 otherwise. Reasons
Expand Down Expand Up @@ -543,6 +512,151 @@ fd_spad_virtual( fd_spad_t * spad ) {
return valloc;
}


/* operation fn implementations */
FD_FN_PURE static inline ulong
fd_spad_alloc_max_impl( fd_spad_t const * spad,
ulong align ) {
align = fd_ulong_if( align>0UL, align, FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
ulong off = fd_ulong_align_up( spad->mem_used, align );
return fd_ulong_max( spad->mem_max, off ) - off;
}

FD_FN_PURE static inline void *
fd_spad_frame_lo_impl( fd_spad_t * spad ) {
return fd_spad_private_mem( spad ) + spad->off[ spad->frame_free ];
}

FD_FN_PURE static inline void *
fd_spad_frame_hi_impl( fd_spad_t * spad ) {
return fd_spad_private_mem( spad ) + spad->mem_used;
}

static inline void
fd_spad_push_impl( fd_spad_t * spad ) {
spad->off[ --spad->frame_free ] = spad->mem_used;
}

static inline void
fd_spad_pop_impl( fd_spad_t * spad ) {
spad->mem_used = spad->off[ spad->frame_free++ ];
}

static inline void
fd_spad_private_frame_end_impl( fd_spad_t ** _spad ) {
fd_spad_pop( *_spad );
}

static inline void *
fd_spad_alloc_impl( fd_spad_t * spad,
ulong align,
ulong sz ) {
align = fd_ulong_if( align>0UL, align, FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
ulong off = fd_ulong_align_up( spad->mem_used, align );
uchar * buf = fd_spad_private_mem( spad ) + off;
spad->mem_used = off + sz;
return buf;
}

static inline void
fd_spad_trim_impl( fd_spad_t * spad,
void * hi ) {
spad->mem_used = (ulong)hi - (ulong)fd_spad_private_mem( spad );
}

static inline void *
fd_spad_prepare_impl( fd_spad_t * spad,
ulong align,
ulong max ) {
(void)max;
align = fd_ulong_if( align>0UL, align, FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
ulong off = fd_ulong_align_up( spad->mem_used, align );
uchar * buf = fd_spad_private_mem( spad ) + off;
spad->mem_used = off;
return buf;
}

static inline void
fd_spad_cancel_impl( fd_spad_t * spad ) {
(void)spad;
}

static inline void
fd_spad_publish_impl( fd_spad_t * spad,
ulong sz ) {
spad->mem_used += sz;
}


/* operation fn definitions */
#ifdef FD_SPAD_USE_HANDHOLDING
#define SELECT_IMPL(fn) fn##_debug
#else
#define SELECT_IMPL(fn) fn##_impl
#endif

FD_FN_PURE ulong
fd_spad_alloc_max( fd_spad_t const * spad,
ulong align ) {
return SELECT_IMPL(fd_spad_alloc_max)(spad, align);
}

FD_FN_PURE void *
fd_spad_frame_lo( fd_spad_t * spad ) {
return SELECT_IMPL(fd_spad_frame_lo)(spad);
}

FD_FN_PURE void *
fd_spad_frame_hi( fd_spad_t * spad ) {
return SELECT_IMPL(fd_spad_frame_hi)(spad);
}

void
fd_spad_push( fd_spad_t * spad ) {
SELECT_IMPL(fd_spad_push)(spad);
}

void
fd_spad_pop(fd_spad_t *spad) {
SELECT_IMPL(fd_spad_pop)(spad);
}

void
fd_spad_private_frame_end(fd_spad_t **_spad) {
SELECT_IMPL(fd_spad_private_frame_end)(_spad);
}

void *
fd_spad_alloc( fd_spad_t * spad,
ulong align,
ulong sz ) {
return SELECT_IMPL(fd_spad_alloc)(spad, align, sz);
}

void
fd_spad_trim( fd_spad_t * spad,
void * hi ) {
SELECT_IMPL(fd_spad_trim)(spad, hi);
}

void *
fd_spad_prepare( fd_spad_t * spad,
ulong align,
ulong max ) {
return SELECT_IMPL(fd_spad_prepare)(spad, align, max);
}

void
fd_spad_cancel(fd_spad_t *spad) {
SELECT_IMPL(fd_spad_cancel)(spad);
}

void
fd_spad_publish( fd_spad_t * spad,
ulong sz ) {
SELECT_IMPL(fd_spad_publish)(spad, sz);
}

FD_PROTOTYPES_END

#endif /* HEADER_fd_src_util_spad_fd_spad_h */

0 comments on commit ad21efc

Please sign in to comment.