this repo has no description
at fixPythonPipStalling 161 lines 4.0 kB view raw
1#include "commpage.h" 2#include <sys/mman.h> 3#include <stdio.h> 4#include <errno.h> 5#include <tgmath.h> 6#include <string.h> 7#include <stdlib.h> 8#include <cpuid.h> 9#include <unistd.h> 10#include <sys/sysinfo.h> 11 12// Include commpage definitions 13#define PRIVATE 14#include <i386/cpu_capabilities.h> 15 16static const char* SIGNATURE32 = "commpage 32-bit"; 17static const char* SIGNATURE64 = "commpage 64-bit"; 18 19static uint64_t get_cpu_caps(void); 20 21#define CGET(p) (commpage + ((p)-_COMM_PAGE_START_ADDRESS)) 22 23void commpage_setup(bool _64bit) 24{ 25 uint8_t* commpage; 26 uint64_t* cpu_caps64; 27 uint32_t* cpu_caps; 28 uint16_t* version; 29 char* signature; 30 uint64_t my_caps; 31 uint8_t *ncpus, *nactivecpus; 32 uint8_t *physcpus, *logcpus; 33 uint8_t *user_page_shift, *kernel_page_shift; 34 struct sysinfo si; 35 36 commpage = (uint8_t*) mmap((void*)(_64bit ? _COMM_PAGE64_BASE_ADDRESS : _COMM_PAGE32_BASE_ADDRESS), 37 _64bit ? _COMM_PAGE64_AREA_LENGTH : _COMM_PAGE32_AREA_LENGTH, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 38 if (commpage == MAP_FAILED) 39 { 40 fprintf(stderr, "Cannot mmap commpage: %s\n", strerror(errno)); 41 exit(1); 42 } 43 44 signature = (char*)CGET(_COMM_PAGE_SIGNATURE); 45 version = (uint16_t*)CGET(_COMM_PAGE_VERSION); 46 cpu_caps64 = (uint64_t*)CGET(_COMM_PAGE_CPU_CAPABILITIES64); 47 cpu_caps = (uint32_t*)CGET(_COMM_PAGE_CPU_CAPABILITIES); 48 49 strcpy(signature, _64bit ? SIGNATURE64 : SIGNATURE32); 50 *version = _COMM_PAGE_THIS_VERSION; 51 52 ncpus = (uint8_t*)CGET(_COMM_PAGE_NCPUS); 53 *ncpus = sysconf(_SC_NPROCESSORS_CONF); 54 55 nactivecpus = (uint8_t*)CGET(_COMM_PAGE_ACTIVE_CPUS); 56 *nactivecpus = sysconf(_SC_NPROCESSORS_ONLN); 57 58 // Better imprecise information than no information 59 physcpus = (uint8_t*)CGET(_COMM_PAGE_PHYSICAL_CPUS); 60 logcpus = (uint8_t*)CGET(_COMM_PAGE_LOGICAL_CPUS); 61 *physcpus = *logcpus = *ncpus; 62 63 // I'm not sure if Linux has separate page sizes for kernel and user space. 64 // Apple's code uses left shift logical (1 << user_page_shift) to get the page size value. 65 // Since it's very unlikely that the page size won't be a power of 2, we can use __builtin_ctzl() 66 // as a substitute for log2(). 67 user_page_shift = (uint8_t*)CGET(_64bit ? _COMM_PAGE_USER_PAGE_SHIFT_64 : _COMM_PAGE_USER_PAGE_SHIFT_32); 68 kernel_page_shift = (uint8_t*)CGET(_COMM_PAGE_KERNEL_PAGE_SHIFT); 69 *kernel_page_shift = *user_page_shift = (uint8_t)__builtin_ctzl(sysconf(_SC_PAGESIZE)); 70 71 my_caps = get_cpu_caps(); 72 if (*ncpus == 1) 73 my_caps |= kUP; 74 75 *cpu_caps = (uint32_t) my_caps; 76 *cpu_caps64 = my_caps; 77 78 if (sysinfo(&si) == 0) 79 { 80 uint64_t* memsize = (uint64_t*)CGET(_COMM_PAGE_MEMORY_SIZE); 81 *memsize = si.totalram * si.mem_unit; 82 } 83} 84 85uint64_t get_cpu_caps(void) 86{ 87 uint64_t caps = 0; 88 89 { 90 union cpu_flags1 eax; 91 union cpu_flags2 ecx; 92 union cpu_flags3 edx; 93 uint32_t ebx; 94 95 eax.reg = ecx.reg = edx.reg = 0; 96 __cpuid(1, eax.reg, ebx, ecx.reg, edx.reg); 97 98 if (ecx.mmx) 99 caps |= kHasMMX; 100 if (ecx.sse) 101 caps |= kHasSSE; 102 if (ecx.sse2) 103 caps |= kHasSSE2; 104 if (edx.sse3) 105 caps |= kHasSSE3; 106 if (ecx.ia64) 107 caps |= k64Bit; 108 if (edx.ssse3) 109 caps |= kHasSupplementalSSE3; 110 if (edx.sse41) 111 caps |= kHasSSE4_1; 112 if (edx.sse42) 113 caps |= kHasSSE4_2; 114 if (edx.aes) 115 caps |= kHasAES; 116 if (edx.avx) 117 caps |= kHasAVX1_0; 118 if (edx.rdrnd) 119 caps |= kHasRDRAND; 120 if (edx.fma) 121 caps |= kHasFMA; 122 if (edx.f16c) 123 caps |= kHasF16C; 124 } 125 { 126 union cpu_flags4 ebx; 127 union cpu_flags5 ecx; 128 uint32_t edx = 0, eax = 7; 129 130 __cpuid(7, eax, ebx.reg, ecx.reg, edx); 131 132 if (ebx.erms) 133 caps |= kHasENFSTRG; 134 if (ebx.avx2) 135 caps |= kHasAVX2_0; 136 if (ebx.bmi1) 137 caps |= kHasBMI1; 138 if (ebx.bmi2) 139 caps |= kHasBMI2; 140 if (ebx.rtm) 141 caps |= kHasRTM; 142 if (ebx.hle) 143 caps |= kHasHLE; 144 if (ebx.rdseed) 145 caps |= kHasRDSEED; 146 if (ebx.adx) 147 caps |= kHasADX; 148 if (ebx.mpx) 149 caps |= kHasMPX; 150 if (ebx.sgx) 151 caps |= kHasSGX; 152 } 153 154 return caps; 155} 156 157unsigned long commpage_address(bool _64bit) 158{ 159 return _64bit ? _COMM_PAGE64_BASE_ADDRESS : _COMM_PAGE32_BASE_ADDRESS; 160} 161