Line data Source code
1 : #include "fd_cpu_topo.h" 2 : 3 : #include "../../util/shmem/fd_shmem_private.h" 4 : #include "../../util/tile/fd_tile_private.h" 5 : 6 : #include <errno.h> 7 : #include <unistd.h> 8 : #include <fcntl.h> 9 : #include <stdio.h> 10 : #include <stdlib.h> 11 : 12 : static uint 13 : read_uint_file( char const * path, 14 0 : char const * errmsg_enoent ) { 15 0 : FILE * fp = fopen( path, "r" ); 16 0 : if( FD_UNLIKELY( !fp ) ) { 17 0 : if( FD_LIKELY( errno==ENOENT ) ) FD_LOG_ERR(( "%s fopen failed `%s` (%i-%s)", errmsg_enoent, path, errno, fd_io_strerror( errno ) )); 18 0 : else FD_LOG_ERR(( "fopen failed `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) )); 19 0 : } 20 : 21 0 : uint value = 0U; 22 0 : if( FD_UNLIKELY( 1!=fscanf( fp, "%u\n", &value ) ) ) FD_LOG_ERR(( "failed to read uint from `%s`", path )); 23 0 : if( FD_UNLIKELY( fclose( fp ) ) ) FD_LOG_ERR(( "fclose failed `%s` (%i-%s)", path, errno, fd_io_strerror( errno ) )); 24 0 : return value; 25 0 : } 26 : 27 : static ulong 28 0 : fd_topo_cpu_cnt( void ) { 29 0 : char path[ PATH_MAX ]; 30 0 : fd_cstr_printf_check( path, PATH_MAX, NULL, "/sys/devices/system/cpu/present" ); 31 : 32 0 : char line[ 128 ]; 33 0 : int fd = open( path, O_RDONLY ); 34 0 : if( FD_UNLIKELY( -1==fd ) ) FD_LOG_ERR(( "open( \"%s\" ) failed (%i-%s)", path, errno, fd_io_strerror( errno ) )); 35 : 36 0 : long bytes_read = read( fd, line, sizeof( line ) ); 37 0 : if( FD_UNLIKELY( -1==bytes_read ) ) FD_LOG_ERR(( "read( \"%s\" ) failed (%i-%s)", path, errno, fd_io_strerror( errno ) )); 38 0 : else if ( FD_UNLIKELY( (ulong)bytes_read>=sizeof( line ) ) ) FD_LOG_ERR(( "read( \"%s\" ) failed: buffer too small", path )); 39 : 40 0 : if( FD_UNLIKELY( close( fd ) ) ) FD_LOG_ERR(( "close( \"%s\" ) failed (%i-%s)", path, errno, fd_io_strerror( errno ) )); 41 : 42 0 : line[ bytes_read ] = '\0'; 43 0 : char * saveptr; 44 0 : char * token = strtok_r( line, "-", &saveptr ); 45 0 : token = strtok_r( NULL, "-", &saveptr ); 46 0 : ulong end = fd_cstr_to_ulong( token ); 47 : 48 0 : return end+1UL; 49 0 : } 50 : 51 : static int 52 0 : fd_topo_cpus_online( ulong cpu_idx ) { 53 0 : if( FD_UNLIKELY( cpu_idx==0UL ) ) return 1; /* Cannot set cpu0 to offline */ 54 : 55 0 : char path[ PATH_MAX ]; 56 0 : FD_TEST( fd_cstr_printf_check( path, sizeof( path ), NULL, "/sys/devices/system/cpu/cpu%lu/online", cpu_idx ) ); 57 0 : return (int)read_uint_file( path, "error reading cpu online status" ); 58 0 : } 59 : 60 : void 61 0 : fd_topo_cpus_init( fd_topo_cpus_t * cpus ) { 62 0 : cpus->numa_node_cnt = fd_numa_node_cnt(); 63 0 : cpus->cpu_cnt = fd_topo_cpu_cnt(); 64 : 65 0 : for( ulong i=0UL; i<cpus->cpu_cnt; i++ ) { 66 0 : cpus->cpu[ i ].idx = i; 67 0 : cpus->cpu[ i ].online = fd_topo_cpus_online( i ); 68 0 : cpus->cpu[ i ].numa_node = fd_numa_node_idx( i ); 69 0 : if( FD_LIKELY( cpus->cpu[ i ].online ) ) cpus->cpu[ i ].sibling = fd_tile_private_sibling_idx( i ); 70 0 : else cpus->cpu[ i ].sibling = ULONG_MAX; 71 0 : } 72 0 : } 73 : 74 : void 75 0 : fd_topo_cpus_printf( fd_topo_cpus_t * cpus ) { 76 0 : for( ulong i=0UL; i<cpus->cpu_cnt; i++ ) { 77 0 : FD_LOG_NOTICE(( "cpu%lu: online=%i sibling=%lu numa_node=%lu", i, cpus->cpu[ i ].online, cpus->cpu[ i ].sibling, cpus->cpu[ i ].numa_node )); 78 0 : } 79 0 : }