LCOV - code coverage report
Current view: top level - util/tile - fd_tile.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 16 19 84.2 %
Date: 2024-11-13 11:58:15 Functions: 14 4396 0.3 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_tile_fd_tile_h
       2             : #define HEADER_fd_src_util_tile_fd_tile_h
       3             : 
       4             : /* Note: fd must be booted to use the APIs in this module */
       5             : 
       6             : /* fd_tile is used for fast dispatching of task within a thread group. */
       7             : 
       8             : #include "../shmem/fd_shmem.h"
       9             : 
      10             : /* FD_TILE_MAX gives a compile tile constant that is the upper bound
      11             :    of the number of tiles that could exist within a thread group. */
      12             : 
      13     4807302 : #define FD_TILE_MAX (1024UL)
      14             : 
      15             : /* A fd_tile_task_t is a function pointer with the function signature
      16             :    for tasks that can be dispatched to a tile. */
      17             : 
      18             : typedef int (*fd_tile_task_t)( int argc, char ** argv );
      19             : 
      20             : /* A fd_tile_exec_t is an opaque handle of a tile execution */
      21             : 
      22             : struct fd_tile_exec_private;
      23             : typedef struct fd_tile_exec_private fd_tile_exec_t;
      24             : 
      25             : /* TODO: Allow this to be run-time configured (e.g. match ulimit -s)? */
      26         180 : #define FD_TILE_PRIVATE_STACK_SZ (8UL<<20) /* Should be a multiple of HUGE (and NORMAL) page sizes */
      27             : 
      28             : FD_PROTOTYPES_BEGIN
      29             : 
      30             : /* fd_tile_{id0,id1,id,idx,cnt} return various information about the
      31             :    calling tile.  Will be constant while tile services are booted. */
      32             : 
      33             : FD_FN_PURE ulong fd_tile_id0( void ); /* Application threads [fd_tile_id0(),fd_tile_id1()) are the caller's thread group */
      34             : FD_FN_PURE ulong fd_tile_id1( void );
      35             : FD_FN_PURE ulong fd_tile_id ( void ); /* == fd_log_thread_id(), in [fd_tile_id0(),fd_tile_id1()) */
      36             : FD_FN_PURE ulong fd_tile_idx( void ); /* == fd_tile_id ()-fd_tile_id0(), in [0,fd_tile_cnt()) */
      37             : FD_FN_PURE ulong fd_tile_cnt( void ); /* == fd_tile_id1()-fd_tile_id0() > 0 */
      38             : 
      39             : /* fd_tile_cpu_id returns the physical cpu_idx used by tile_idx.  This
      40             :    matches the --tile-cpus / FD_TILE_CPUS configuration extracted from
      41             :    the command line / environment when tile services were booted.  Will
      42             :    be constant while tile services are booted.  Returns ULONG_MAX if
      43             :    tile_idx is not in [0,td_tile_cnt()) and ULONG_MAX-1 if tile_idx was
      44             :    configured to float. */
      45             : 
      46             : FD_FN_PURE ulong fd_tile_cpu_id( ulong tile_idx );
      47             : 
      48             : /* Tile stack diagnostics.  These are meant to help with instrumenting
      49             :    and debugging stack issues but usually should not be used in final
      50             :    production code.  For reference, tile 0's stack size is usually set
      51             :    at thread group start with the size in KiB given by "ulimit -s".
      52             :    This is typically 8 MiB and dynamically backed by normal 4 KiB pages.
      53             :    Other tiles usually have a size of a not-so-coincidentally 8 MiB but
      54             :    are backed by preallocated NUMA and TLB optimized huge 2 MiB pages.
      55             :    Additionally, tile stacks are usually bookended by guard regions that
      56             :    are 4 KiB in size to protect against common stack overflow /
      57             :    underflow risks.  The below assumes the stack grows from higher
      58             :    addresses (i.e. stack1) toward lower addresses (i.e. stack0).
      59             : 
      60             :    [fd_tile_stack0(),fd_tile_stack1()) gives the location in caller's
      61             :    local address space the caller's stack.  The size of this region is
      62             :    fd_tile_stack_sz().  fd_tile_stack_est_used() and
      63             :    fd_tile_stack_est_free() are estimates of the number of bytes in the
      64             :    stack currently used and currently free.
      65             : 
      66             :    If the tile stack parameters could not be determined at tile startup,
      67             :    details will be logged and stack0/stack1/stack_sz/est_used/est_free
      68             :    will be NULL/NULL/0/0/0. */
      69             : 
      70             : extern FD_TL ulong fd_tile_private_stack0;
      71             : extern FD_TL ulong fd_tile_private_stack1;
      72             : 
      73          18 : static inline void const * fd_tile_stack0  ( void ) { return (void const *)fd_tile_private_stack0; }
      74          18 : static inline void const * fd_tile_stack1  ( void ) { return (void const *)fd_tile_private_stack1; }
      75          18 : static inline ulong        fd_tile_stack_sz( void ) { return fd_tile_private_stack1 - fd_tile_private_stack0; }
      76             : 
      77             : static inline ulong
      78          18 : fd_tile_stack_est_used( void ) {
      79          18 :   uchar stack_mem[1];
      80          18 :   FD_VOLATILE( stack_mem[0] ) = (uchar)1; /* Paranoia to guarantee stack_mem is on the stack and backed by memory */
      81          18 :   return fd_ulong_if( !fd_tile_private_stack1, 0UL, fd_tile_private_stack1 - (ulong)stack_mem );
      82          18 : }
      83             : 
      84             : static inline ulong
      85        6531 : fd_tile_stack_est_free( void ) {
      86        6531 :   uchar stack_mem[1];
      87        6531 :   FD_VOLATILE( stack_mem[0] ) = (uchar)1; /* Paranoia to guarantee stack_mem is on the stack and backed by memory */
      88        6531 :   return fd_ulong_if( !fd_tile_private_stack0, 0UL, (ulong)stack_mem - fd_tile_private_stack0 );
      89        6531 : }
      90             : 
      91             : /* fd_tile_exec_new starts parallel execution of task( argc, argv ) on
      92             :    tile idx (in [0,fd_tile_cnt()).  Returns a handle for this exec on
      93             :    success (tile idx was signaled to start execution of task) or NULL on
      94             :    failure (e.g.  tried to dispatch to self or tried dispatch to tile 0,
      95             :    another exec is currently running on that tile id, tried to dispatch
      96             :    to a thread in a different thread group, etc).
      97             : 
      98             :    task, argc, argv and argv[0:argc] are intended to be in this thread
      99             :    group's address space and argc and argv are intended (but not
     100             :    required) to be POSIX-like command line interface such that argc>0,
     101             :    argv[0] is the task name, argv[argc]==NULL and argv[0:argc-1] are all
     102             :    non-NULL cstrs.  On success, the returned exec has ownership of argv
     103             :    and all cstrs pointed to by it.  On failure, ownership is unchanged.
     104             : 
     105             :    Typically, a tile can't dispatch to itself or to tile 0. */
     106             : 
     107             : fd_tile_exec_t *
     108             : fd_tile_exec_new( ulong          idx,  /* In [0,fd_tile_cnt()) */
     109             :                   fd_tile_task_t task, /* Non-NULL */
     110             :                   int            argc,
     111             :                   char **        argv );
     112             : 
     113             : /* fd_tile_exec_by_id_new same as the above but tile to run is specified
     114             :    by the application thread index. */
     115             : 
     116             : static inline fd_tile_exec_t *
     117             : fd_tile_exec_by_id_new( ulong          id,   /* In [fd_tile_id0(),fd_tile_id1()) */
     118             :                         fd_tile_task_t task, /* Non-NULL */
     119             :                         int            argc,
     120           0 :                         char **        argv ) {
     121           0 :   return fd_tile_exec_new( id-fd_tile_id0(), task, argc, argv );
     122           0 : }
     123             : 
     124             : /* fd_tile_exec_delete deletes the given exec, blocking the caller if
     125             :    necessary (will be non-blocking if the exec is done).  Returns NULL
     126             :    if the exec terminated normally (if opt_ret is non-NULL and *opt_ret
     127             :    will be the value returned by the tile task) or an infinite lifetime
     128             :    cstr if the exec terminated abnormally (e.g. had an uncaught
     129             :    exception, called exit ... yes, currently tile tasks must return for
     130             :    normal termination, called abort, etc ... opt_ret will be
     131             :    non-touched). */
     132             : 
     133             : char const *
     134             : fd_tile_exec_delete( fd_tile_exec_t * exec,
     135             :                      int *            opt_ret );
     136             : 
     137             : /* fd_tile_exec returns the fd_tile_exec_t * running on tile tile_idx.
     138             :    fd_tile_exec_by_id_new same but tile to specified by the application
     139             :    thread index.  Undefined if tile_idx is not in [0,fd_tile_cnt()) (or
     140             :    tile_id is not in [fd_tile_id0(),fd_tile_id1()) or called outside a
     141             :    fd_tile_exec*_new / fd_tile_exec_delete pair. */
     142             : 
     143             : FD_FN_PURE fd_tile_exec_t * fd_tile_exec( ulong tile_idx );
     144             : 
     145          12 : static inline fd_tile_exec_t * fd_tile_exec_by_id( ulong tile_id ) { return fd_tile_exec( tile_id-fd_tile_id0() ); }
     146             : 
     147             : /* fd_tile_exec_{id,idx,task,argc,argv} access details exec pointed to
     148             :    by exec.  These assume exec points to a current exec. */
     149             : 
     150             : FD_FN_PURE ulong          fd_tile_exec_id  ( fd_tile_exec_t const * exec );
     151             : FD_FN_PURE ulong          fd_tile_exec_idx ( fd_tile_exec_t const * exec );
     152             : FD_FN_PURE fd_tile_task_t fd_tile_exec_task( fd_tile_exec_t const * exec );
     153             : FD_FN_PURE int            fd_tile_exec_argc( fd_tile_exec_t const * exec );
     154             : FD_FN_PURE char **        fd_tile_exec_argv( fd_tile_exec_t const * exec );
     155             : 
     156             : /* fd_tile_exec_done returns 0 if the given exec is still running or 1
     157             :    if it has stopped.  Assumes exec points to a current exec. */
     158             : 
     159             : int fd_tile_exec_done( fd_tile_exec_t const * exec );
     160             : 
     161             : /* These functions are for fd_util internal use only. */
     162             : 
     163             : void
     164             : fd_tile_private_boot( int *    pargc,
     165             :                       char *** pargv );
     166             : 
     167             : void
     168             : fd_tile_private_map_boot( ushort * tile_to_cpu,
     169             :                           ulong    tile_cnt );
     170             : 
     171             : void
     172             : fd_tile_private_halt( void );
     173             : 
     174             : FD_PROTOTYPES_END
     175             : 
     176             : #endif /* HEADER_fd_src_util_tile_fd_tile_h */

Generated by: LCOV version 1.14