Skip to content

Commit b514cfe

Browse files
riptlripatel-fd
authored andcommitted
funk: simplify 'try_clone_safe' into 'insert_para'
Remove record allocation and copy from try_clone_safe. Existing callers effectively only use this API as 'update existing record'.
1 parent 80e6a29 commit b514cfe

File tree

6 files changed

+37
-76
lines changed

6 files changed

+37
-76
lines changed

src/flamenco/runtime/program/fd_program_cache.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -573,18 +573,13 @@ FD_SPAD_FRAME_BEGIN( runtime_spad ) {
573573
record_sz = fd_program_cache_entry_footprint( &elf_info );
574574
}
575575

576-
/* Copy the record (if needed) down into the current funk txn from one
577-
of its ancestors.
578-
579-
TODO: We pass in a `min_sz` of 0 because this API does not resize
580-
the record if it already exists in the current funk transaction.
581-
This maybe needs to change. */
582-
fd_funk_rec_try_clone_safe( slot_ctx->funk, slot_ctx->funk_txn, &id, 0UL, 0UL );
576+
/* Insert a new funk record, replacing the existing one if needed.
577+
min_sz==0 since the actual allocation happens below. */
578+
fd_funk_rec_insert_para( slot_ctx->funk, slot_ctx->funk_txn, &id );
583579

584580
/* Modify the record within the current funk txn */
585581
fd_funk_rec_query_t query[1];
586582
fd_funk_rec_t * rec = fd_funk_rec_modify( slot_ctx->funk, slot_ctx->funk_txn, &id, query );
587-
588583
if( FD_UNLIKELY( !rec ) ) {
589584
/* The record does not exist (somehow). Ideally this should never
590585
happen as this function is called in a single-threaded context. */
@@ -648,24 +643,34 @@ fd_program_cache_queue_program_for_reverification( fd_funk_t * funk,
648643

649644
/* Ensure the record is in the current funk transaction */
650645
fd_funk_rec_key_t id = fd_program_cache_key( program_key );
651-
fd_funk_rec_try_clone_safe( funk, funk_txn, &id, 0UL, 0UL );
646+
fd_funk_rec_insert_para( funk, funk_txn, &id );
652647

653648
/* Modify the record within the current funk txn */
654649
fd_funk_rec_query_t query[1];
655650
fd_funk_rec_t * rec = fd_funk_rec_modify( funk, funk_txn, &id, query );
656-
657651
if( FD_UNLIKELY( !rec ) ) {
658652
/* The record does not exist (somehow). Ideally this should never
659653
happen since this function is called in a single-threaded
660654
context. */
661655
FD_LOG_CRIT(( "Failed to modify the BPF program cache record. Perhaps there is a race condition?" ));
662656
}
663657

664-
void * data = fd_funk_val( rec, fd_funk_wksp( funk ) );
665-
fd_program_cache_entry_t * writable_entry = fd_type_pun( data );
658+
/* Insert a tombstone */
659+
if( FD_UNLIKELY( !fd_funk_val_truncate(
660+
rec,
661+
fd_funk_alloc( funk ),
662+
fd_funk_wksp( funk ),
663+
alignof(fd_program_cache_entry_t),
664+
sizeof(fd_program_cache_entry_t),
665+
NULL ) ) ) {
666+
FD_LOG_ERR(( "fd_funk_val_truncate() failed (out of memory?)" ));
667+
}
666668

667-
/* Set the last modified slot to the current slot */
668-
writable_entry->last_slot_modified = current_slot;
669+
fd_program_cache_entry_t * entry = fd_funk_val( rec, fd_funk_wksp( funk ) );
670+
*entry = (fd_program_cache_entry_t) {
671+
.magic = FD_PROGRAM_CACHE_ENTRY_MAGIC,
672+
.last_slot_modified = current_slot
673+
};
669674

670675
/* Finish modifying and release lock */
671676
fd_funk_rec_modify_publish( query );

src/flamenco/runtime/program/test_program_cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ test_program_in_cache_queued_for_reverification( void ) {
315315
FD_TEST( valid_prog->magic==FD_PROGRAM_CACHE_ENTRY_MAGIC );
316316
FD_TEST( !valid_prog->failed_verification );
317317
FD_TEST( valid_prog->last_slot_modified==future_slot );
318-
FD_TEST( valid_prog->last_slot_verified==original_slot );
318+
FD_TEST( valid_prog->last_slot_verified==0UL );
319319
FD_TEST( valid_prog->last_slot_modified>original_slot );
320320

321321
/* Reverify the cache entry at the future slot */
@@ -421,7 +421,7 @@ test_program_in_cache_queued_for_reverification_and_processed( void ) {
421421
FD_TEST( valid_prog->magic==FD_PROGRAM_CACHE_ENTRY_MAGIC );
422422
FD_TEST( !valid_prog->failed_verification );
423423
FD_TEST( valid_prog->last_slot_modified==future_slot );
424-
FD_TEST( valid_prog->last_slot_verified==original_slot );
424+
FD_TEST( valid_prog->last_slot_verified==0UL );
425425
FD_TEST( valid_prog->last_slot_modified>original_slot );
426426

427427
/* Fast forward to a future slot */

src/funk/fd_funk_rec.c

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,9 @@ fd_funk_rec_txn_publish( fd_funk_t * funk,
328328
}
329329

330330
void
331-
fd_funk_rec_try_clone_safe( fd_funk_t * funk,
332-
fd_funk_txn_t * txn,
333-
fd_funk_rec_key_t const * key,
334-
ulong align,
335-
ulong min_sz ) {
331+
fd_funk_rec_insert_para( fd_funk_t * funk,
332+
fd_funk_txn_t * txn,
333+
fd_funk_rec_key_t const * key ) {
336334

337335
/* TODO: There is probably a cleaner way to allocate the txn memory. */
338336

@@ -414,36 +412,10 @@ fd_funk_rec_try_clone_safe( fd_funk_t * funk,
414412
(if one exists). */
415413

416414
fd_funk_rec_prepare_t prepare[1];
417-
fd_funk_rec_t * new_rec = fd_funk_rec_prepare( funk, txn, key, prepare, &err );
415+
fd_funk_rec_prepare( funk, txn, key, prepare, &err );
418416
if( FD_UNLIKELY( err ) ) {
419417
FD_LOG_CRIT(( "fd_funk_rec_prepare returned err=%d", err ));
420418
}
421-
422-
/* It is fine to use the old version of the record because we can
423-
assume that it comes from a frozen txn. */
424-
ulong old_val_sz = !!rec_glob ? rec_glob->val_sz : 0UL;
425-
ulong new_val_sz = fd_ulong_max( old_val_sz, min_sz );
426-
427-
uchar * new_val = fd_funk_val_truncate(
428-
new_rec,
429-
fd_funk_alloc( funk ),
430-
fd_funk_wksp( funk ),
431-
align,
432-
new_val_sz,
433-
&err );
434-
if( FD_UNLIKELY( err ) ) {
435-
FD_LOG_CRIT(( "fd_funk_val_truncate returned err=%d", err ));
436-
}
437-
if( FD_UNLIKELY( !new_val ) ) {
438-
FD_LOG_CRIT(( "fd_funk_val_truncate returned NULL" ));
439-
}
440-
441-
if( rec_glob ) {
442-
/* If we have a global copy of the record, copy it in. */
443-
uchar * old_data = fd_funk_val( rec_glob, fd_funk_wksp( funk ) );
444-
memcpy( new_val, old_data, old_val_sz );
445-
}
446-
447419
fd_funk_rec_txn_publish( funk, prepare );
448420

449421
err = fd_funk_rec_map_txn_test( map_txn );

src/funk/fd_funk_rec.h

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,7 @@ fd_funk_rec_cancel( fd_funk_t * funk,
310310
modified afterward and must then be published.
311311
312312
NOTE: fd_funk_rec_clone is NOT thread safe and should not be used
313-
concurrently with other funk read/write operations.
314-
315-
FIXME: This function should be removed in favor of
316-
fd_funk_rec_try_clone_safe. */
313+
concurrently with other funk read/write operations. */
317314

318315
fd_funk_rec_t *
319316
fd_funk_rec_clone( fd_funk_t * funk,
@@ -322,11 +319,7 @@ fd_funk_rec_clone( fd_funk_t * funk,
322319
fd_funk_rec_prepare_t * prepare,
323320
int * opt_err );
324321

325-
/* fd_funk_rec_try_clone_safe is the thread-safe analog to
326-
fd_funk_rec_clone. This function will try to atomically query and
327-
copy the given funk record from the youngest ancestor transaction
328-
of the given txn and copy it into a new record of the same key into
329-
the current funk txn.
322+
/* fd_funk_rec_insert_para does thread-safe insertion of a funk record.
330323
331324
Detailed Behavior:
332325
@@ -345,22 +338,14 @@ fd_funk_rec_clone( fd_funk_t * funk,
345338
that we were attempting to acquire the lock. If a keypair is found,
346339
we will free the lock and exit the function.
347340
348-
Otherwise, we will allocate the account and copy over the data from
349-
the ancestor record. Now we will add this into the record map. At
350-
this point, we can now free the lock on the hash chain.
351-
352-
The caller can specify the alignment and min_sz they would like for
353-
the value of the record. If the caller wishes to use default
354-
alignment, they can pass 0UL (see fd_funk_val_truncate() for more
355-
details). */
341+
Otherwise, we will allocate a new account record. Now we will add
342+
this into the record map. At this point, we can now free the lock on
343+
the hash chain. */
356344

357345
void
358-
fd_funk_rec_try_clone_safe( fd_funk_t * funk,
359-
fd_funk_txn_t * txn,
360-
fd_funk_rec_key_t const * key,
361-
ulong align,
362-
ulong min_sz );
363-
346+
fd_funk_rec_insert_para( fd_funk_t * funk,
347+
fd_funk_txn_t * txn,
348+
fd_funk_rec_key_t const * key );
364349

365350
/* fd_funk_rec_remove removes the live record with the
366351
given (xid,key) from funk. Returns FD_FUNK_SUCCESS (0) on

src/funk/fd_funk_val.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ fd_funk_val_max( fd_funk_rec_t const * rec ) { /* Assumes pointer in caller's ad
4141

4242
FD_FN_PURE static inline void * /* Lifetime is the lesser of rec or the value size is modified */
4343
fd_funk_val( fd_funk_rec_t const * rec, /* Assumes pointer in caller's address space to a live funk record */
44-
fd_wksp_t const * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */
44+
fd_wksp_t const * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */
4545
ulong val_gaddr = rec->val_gaddr;
4646
if( !val_gaddr ) return NULL; /* Covers the marked ERASE case too */ /* TODO: consider branchless */
4747
return fd_wksp_laddr_fast( wksp, val_gaddr );
4848
}
4949

5050
FD_FN_PURE static inline void const * /* Lifetime is the lesser of rec or the value size is modified */
5151
fd_funk_val_const( fd_funk_rec_t const * rec, /* Assumes pointer in caller's address space to a live funk record */
52-
fd_wksp_t const * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */
52+
fd_wksp_t const * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */
5353
ulong val_gaddr = rec->val_gaddr;
5454
if( !val_gaddr ) return NULL; /* Covers the marked ERASE case too */ /* TODO: consider branchless */
5555
return fd_wksp_laddr_fast( wksp, val_gaddr );

src/funk/test_funk_concur2.cxx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,18 @@ static void * work_thread( void * arg ) {
2828
key.ul[0] = key_idx;
2929

3030
/* First try to clone the record from the ancestor. */
31-
fd_funk_rec_try_clone_safe( funk, txn, &key, alignof(ulong), sizeof(ulong) );
31+
fd_funk_rec_insert_para( funk, txn, &key );
3232

3333
/* Ensure that the record exists for the current txn. */
34-
3534
fd_funk_rec_query_t query_check[1];
3635
fd_funk_rec_t const * rec_check = fd_funk_rec_query_try( funk, txn, &key, query_check );
3736
FD_TEST( rec_check );
3837

3938
/* Now modify the record. */
40-
4139
fd_funk_rec_query_t query_modify[1];
4240
fd_funk_rec_t * rec = fd_funk_rec_modify( funk, txn, &key, query_modify );
4341
FD_TEST( rec );
42+
FD_TEST( fd_funk_val_truncate( rec, fd_funk_alloc( funk ), fd_funk_wksp( funk ), alignof(ulong), sizeof(ulong), NULL ) );
4443
void * val = fd_funk_val( rec, fd_funk_wksp(funk) );
4544
ulong * val_ul = (ulong *)val;
4645
*val_ul += 1UL;

0 commit comments

Comments
 (0)