Line data Source code
1 : #define _GNU_SOURCE 2 : #include <errno.h> 3 : #include <sched.h> 4 : 5 : #include <unistd.h> 6 : #include <fcntl.h> 7 : #include <stdio.h> 8 : #include <stdlib.h> 9 : #include <ctype.h> 10 : 11 : #include "fd_tile_private.h" 12 : 13 : int 14 : fd_cpuset_getaffinity( ulong pid, 15 14 : fd_cpuset_t * mask ) { 16 14 : # if defined(__linux__) 17 14 : return sched_getaffinity( (int)pid, fd_cpuset_word_cnt<<3, (cpu_set_t *)fd_type_pun( mask ) ); 18 : # else 19 : (void)pid; (void)mask; 20 : errno = ENOTSUP; 21 : return -1; 22 : # endif 23 14 : } 24 : 25 : int 26 : fd_cpuset_setaffinity( ulong pid, 27 0 : fd_cpuset_t const * mask ) { 28 0 : # if defined(__linux__) 29 0 : return sched_setaffinity( (int)pid, fd_cpuset_word_cnt<<3, (cpu_set_t const *)fd_type_pun_const( mask ) ); 30 : # else 31 : (void)pid; (void)mask; 32 : errno = ENOTSUP; 33 : return -1; 34 : # endif 35 0 : } 36 : 37 : ulong 38 : fd_tile_private_sibling_parse( char const * list, 39 0 : ulong cpu_idx ) { 40 0 : ulong cnt = 0UL; 41 0 : ulong other = ULONG_MAX; 42 0 : int found = 0; 43 0 : char const * p = list; 44 0 : for(;;) { 45 0 : if( FD_UNLIKELY( !fd_isdigit( (int)p[0] ) ) ) return ULONG_MAX-1UL; 46 0 : char * end; 47 0 : ulong lo = strtoul( p, &end, 10 ); 48 0 : ulong hi = lo; 49 0 : p = end; 50 0 : if( p[0]=='-' ) { 51 0 : p++; 52 0 : if( FD_UNLIKELY( !fd_isdigit( (int)p[0] ) ) ) return ULONG_MAX-1UL; 53 0 : hi = strtoul( p, &end, 10 ); 54 0 : p = end; 55 0 : } 56 0 : if( FD_UNLIKELY( hi<lo || hi>=FD_TILE_MAX ) ) return ULONG_MAX-1UL; 57 0 : cnt += hi-lo+1UL; 58 0 : if( cpu_idx>=lo && cpu_idx<=hi ) found = 1; 59 0 : if( lo!=cpu_idx ) other = lo; 60 0 : else if( hi!=cpu_idx ) other = hi; 61 0 : if( p[0]!=',' ) break; 62 0 : p++; 63 0 : } 64 0 : if( FD_UNLIKELY( !( p[0]=='\0' || ( p[0]=='\n' && p[1]=='\0' ) ) || !found || cnt>2UL ) ) return ULONG_MAX-1UL; 65 0 : return cnt==2UL ? other : ULONG_MAX; 66 0 : } 67 : 68 : ulong 69 0 : fd_tile_private_sibling_idx( ulong cpu_idx ) { 70 0 : # if defined(__linux__) 71 0 : char path[ PATH_MAX ]; 72 0 : FD_TEST( fd_cstr_printf_check( path, PATH_MAX, NULL, "/sys/devices/system/cpu/cpu%lu/topology/thread_siblings_list", cpu_idx ) ); 73 : 74 0 : int fd = open( path, O_RDONLY ); 75 0 : if( FD_UNLIKELY( -1==fd ) ) FD_LOG_ERR(( "open( \"%s\" ) failed (%i-%s)", path, errno, fd_io_strerror( errno ) )); 76 : 77 0 : char line[ 1024 ] = {0}; 78 0 : long bytes_read = read( fd, line, sizeof( line ) ); 79 0 : if( FD_UNLIKELY( -1==bytes_read ) ) FD_LOG_ERR(( "read( \"%s\" ) failed (%i-%s)", path, errno, fd_io_strerror( errno ) )); 80 0 : else if ( FD_UNLIKELY( (ulong)bytes_read>=sizeof( line ) ) ) FD_LOG_ERR(( "read( \"%s\" ) failed: buffer too small", path )); 81 : 82 0 : if( FD_UNLIKELY( close( fd ) ) ) FD_LOG_ERR(( "close( \"%s\" ) failed (%i-%s)", path, errno, fd_io_strerror( errno ) )); 83 : 84 0 : ulong sibling = fd_tile_private_sibling_parse( line, cpu_idx ); 85 0 : if( FD_UNLIKELY( sibling==ULONG_MAX-1UL ) ) FD_LOG_ERR(( "failed to parse cpu siblings list of cpu%lu `%s`", cpu_idx, line )); 86 0 : return sibling; 87 : # else 88 : (void)cpu_idx; 89 : return ULONG_MAX; 90 : # endif 91 0 : }