274 //
275 // If "/jre/lib/" does NOT appear at the right place in the path
276 // instead of exit check for $JAVA_HOME environment variable.
277 //
278 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
279 // then we append a fake suffix "hotspot/libjvm.so" to this path so
280 // it looks like libjvm.so is installed there
281 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
282 //
283 // Otherwise exit.
284 //
285 // Important note: if the location of libjvm.so changes this
286 // code needs to be changed accordingly.
287
288 // See ld(1):
289 // The linker uses the following search paths to locate required
290 // shared libraries:
291 // 1: ...
292 // ...
293 // 7: The default directories, normally /lib and /usr/lib.
294 #if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390))
295 #define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
296 #else
297 #define DEFAULT_LIBPATH "/lib:/usr/lib"
298 #endif
299
300 // Base path of extensions installed on the system.
301 #define SYS_EXT_DIR "/usr/java/packages"
302 #define EXTENSIONS_DIR "/lib/ext"
303
304 // Buffer that fits several sprintfs.
305 // Note that the space for the colon and the trailing null are provided
306 // by the nulls included by the sizeof operator.
307 const size_t bufsize =
308 MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.
309 (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir
310 char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
311
312 // sysclasspath, java_home, dll_dir
313 {
314 char *pslash;
1195 // resolution for now. Hopefully as people move to new kernels, this
1196 // won't be a problem.
1197 struct timespec res;
1198 struct timespec tp;
1199 if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
1200 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
1201 // yes, monotonic clock is supported
1202 _clock_gettime = clock_gettime_func;
1203 return;
1204 } else {
1205 // close librt if there is no monotonic clock
1206 dlclose(handle);
1207 }
1208 }
1209 }
1210 warning("No monotonic clock was available - timed services may " \
1211 "be adversely affected if the time-of-day clock changes");
1212 }
1213
1214 #ifndef SYS_clock_getres
1215 #if defined(IA32) || defined(AMD64)
1216 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229)
1217 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1218 #else
1219 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
1220 #define sys_clock_getres(x,y) -1
1221 #endif
1222 #else
1223 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1224 #endif
1225
1226 void os::Linux::fast_thread_clock_init() {
1227 if (!UseLinuxPosixThreadCPUClocks) {
1228 return;
1229 }
1230 clockid_t clockid;
1231 struct timespec tp;
1232 int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
1233 (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
1234
1235 // Switch to using fast clocks for thread cpu time if
1236 // the sys_clock_getres() returns 0 error code.
1749 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
1750 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
1751 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"},
1752 {EM_AARCH64, EM_AARCH64, ELFCLASS64, ELFDATA2LSB, (char*)"AARCH64"},
1753 };
1754
1755 #if (defined IA32)
1756 static Elf32_Half running_arch_code=EM_386;
1757 #elif (defined AMD64)
1758 static Elf32_Half running_arch_code=EM_X86_64;
1759 #elif (defined IA64)
1760 static Elf32_Half running_arch_code=EM_IA_64;
1761 #elif (defined __sparc) && (defined _LP64)
1762 static Elf32_Half running_arch_code=EM_SPARCV9;
1763 #elif (defined __sparc) && (!defined _LP64)
1764 static Elf32_Half running_arch_code=EM_SPARC;
1765 #elif (defined __powerpc64__)
1766 static Elf32_Half running_arch_code=EM_PPC64;
1767 #elif (defined __powerpc__)
1768 static Elf32_Half running_arch_code=EM_PPC;
1769 #elif (defined ARM)
1770 static Elf32_Half running_arch_code=EM_ARM;
1771 #elif (defined S390)
1772 static Elf32_Half running_arch_code=EM_S390;
1773 #elif (defined ALPHA)
1774 static Elf32_Half running_arch_code=EM_ALPHA;
1775 #elif (defined MIPSEL)
1776 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
1777 #elif (defined PARISC)
1778 static Elf32_Half running_arch_code=EM_PARISC;
1779 #elif (defined MIPS)
1780 static Elf32_Half running_arch_code=EM_MIPS;
1781 #elif (defined M68K)
1782 static Elf32_Half running_arch_code=EM_68K;
1783 #elif (defined AARCH64)
1784 static Elf32_Half running_arch_code=EM_AARCH64;
1785 #else
1786 #error Method os::dll_load requires that one of following is defined:\
1787 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K, AARCH64
1788 #endif
1789
1790 // Identify compatability class for VM's architecture and library's architecture
1791 // Obtain string descriptions for architectures
1792
1793 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
1794 int running_arch_index=-1;
1795
1796 for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) {
1797 if (running_arch_code == arch_array[i].code) {
1798 running_arch_index = i;
1799 }
1800 if (lib_arch.code == arch_array[i].code) {
1801 lib_arch.compat_class = arch_array[i].compat_class;
1802 lib_arch.name = arch_array[i].name;
1803 }
1804 }
1805
1806 assert(running_arch_index != -1,
1807 "Didn't find running architecture code (running_arch_code) in arch_array");
2175 }
2176 }
2177 fclose(fp);
2178 }
2179 #endif // x86 platforms
2180 return false;
2181 }
2182
2183 void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
2184 // Only print the model name if the platform provides this as a summary
2185 if (!print_model_name_and_flags(st, buf, buflen)) {
2186 st->print("\n/proc/cpuinfo:\n");
2187 if (!_print_ascii_file("/proc/cpuinfo", st)) {
2188 st->print_cr(" <Not Available>");
2189 }
2190 }
2191 }
2192
2193 #if defined(AMD64) || defined(IA32) || defined(X32)
2194 const char* search_string = "model name";
2195 #elif defined(SPARC)
2196 const char* search_string = "cpu";
2197 #elif defined(PPC64)
2198 const char* search_string = "cpu";
2199 #else
2200 const char* search_string = "Processor";
2201 #endif
2202
2203 // Parses the cpuinfo file for string representing the model name.
2204 void os::get_summary_cpu_info(char* cpuinfo, size_t length) {
2205 FILE* fp = fopen("/proc/cpuinfo", "r");
2206 if (fp != NULL) {
2207 while (!feof(fp)) {
2208 char buf[256];
2209 if (fgets(buf, sizeof(buf), fp)) {
2210 char* start = strstr(buf, search_string);
2211 if (start != NULL) {
2212 char *ptr = start + strlen(search_string);
2213 char *end = buf + strlen(buf);
2214 while (ptr != end) {
2215 // skip whitespace and colon for the rest of the name.
2216 if (*ptr != ' ' && *ptr != '\t' && *ptr != ':') {
2217 break;
2218 }
2219 ptr++;
2220 }
2221 if (ptr != end) {
2222 // reasonable string, get rid of newline and keep the rest
2223 char* nl = strchr(buf, '\n');
2224 if (nl != NULL) *nl = '\0';
2225 strncpy(cpuinfo, ptr, length);
2226 fclose(fp);
2227 return;
2228 }
2229 }
2230 }
2231 }
2232 fclose(fp);
2233 }
2234 // cpuinfo not found or parsing failed, just print generic string. The entire
2235 // /proc/cpuinfo file will be printed later in the file (or enough of it for x86)
2236 #if defined(AMD64)
2237 strncpy(cpuinfo, "x86_64", length);
2238 #elif defined(IA32)
2239 strncpy(cpuinfo, "x86_32", length);
2240 #elif defined(IA64)
2241 strncpy(cpuinfo, "IA64", length);
2242 #elif defined(SPARC)
2243 strncpy(cpuinfo, "sparcv9", length);
2244 #elif defined(AARCH64)
2245 strncpy(cpuinfo, "AArch64", length);
2246 #elif defined(ARM)
2247 strncpy(cpuinfo, "ARM", length);
2248 #elif defined(PPC)
2249 strncpy(cpuinfo, "PPC64", length);
2250 #elif defined(ZERO_LIBARCH)
2251 strncpy(cpuinfo, ZERO_LIBARCH, length);
2252 #else
2253 strncpy(cpuinfo, "unknown", length);
2254 #endif
2255 }
2256
2257 static void print_signal_handler(outputStream* st, int sig,
2258 char* buf, size_t buflen);
2259
2260 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
2261 st->print_cr("Signal Handlers:");
2262 print_signal_handler(st, SIGSEGV, buf, buflen);
2263 print_signal_handler(st, SIGBUS , buf, buflen);
2264 print_signal_handler(st, SIGFPE , buf, buflen);
2265 print_signal_handler(st, SIGPIPE, buf, buflen);
2266 print_signal_handler(st, SIGXFSZ, buf, buflen);
2267 print_signal_handler(st, SIGILL , buf, buflen);
2268 print_signal_handler(st, SR_signum, buf, buflen);
2269 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
3225
3226 static size_t _large_page_size = 0;
3227
3228 size_t os::Linux::find_large_page_size() {
3229 size_t large_page_size = 0;
3230
3231 // large_page_size on Linux is used to round up heap size. x86 uses either
3232 // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
3233 // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
3234 // page as large as 256M.
3235 //
3236 // Here we try to figure out page size by parsing /proc/meminfo and looking
3237 // for a line with the following format:
3238 // Hugepagesize: 2048 kB
3239 //
3240 // If we can't determine the value (e.g. /proc is not mounted, or the text
3241 // format has been changed), we'll use the largest page size supported by
3242 // the processor.
3243
3244 #ifndef ZERO
3245 large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
3246 ARM32_ONLY(2 * M) PPC_ONLY(4 * M) AARCH64_ONLY(2 * M);
3247 #endif // ZERO
3248
3249 FILE *fp = fopen("/proc/meminfo", "r");
3250 if (fp) {
3251 while (!feof(fp)) {
3252 int x = 0;
3253 char buf[16];
3254 if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
3255 if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
3256 large_page_size = x * K;
3257 break;
3258 }
3259 } else {
3260 // skip to next line
3261 for (;;) {
3262 int ch = fgetc(fp);
3263 if (ch == EOF || ch == (int)'\n') break;
3264 }
3265 }
3266 }
|
274 //
275 // If "/jre/lib/" does NOT appear at the right place in the path
276 // instead of exit check for $JAVA_HOME environment variable.
277 //
278 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
279 // then we append a fake suffix "hotspot/libjvm.so" to this path so
280 // it looks like libjvm.so is installed there
281 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
282 //
283 // Otherwise exit.
284 //
285 // Important note: if the location of libjvm.so changes this
286 // code needs to be changed accordingly.
287
288 // See ld(1):
289 // The linker uses the following search paths to locate required
290 // shared libraries:
291 // 1: ...
292 // ...
293 // 7: The default directories, normally /lib and /usr/lib.
294 #if defined(AMD64) || (defined(_LP64) && defined(SPARC)) || defined(PPC64) || defined(S390)
295 #define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
296 #else
297 #define DEFAULT_LIBPATH "/lib:/usr/lib"
298 #endif
299
300 // Base path of extensions installed on the system.
301 #define SYS_EXT_DIR "/usr/java/packages"
302 #define EXTENSIONS_DIR "/lib/ext"
303
304 // Buffer that fits several sprintfs.
305 // Note that the space for the colon and the trailing null are provided
306 // by the nulls included by the sizeof operator.
307 const size_t bufsize =
308 MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.
309 (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir
310 char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
311
312 // sysclasspath, java_home, dll_dir
313 {
314 char *pslash;
1195 // resolution for now. Hopefully as people move to new kernels, this
1196 // won't be a problem.
1197 struct timespec res;
1198 struct timespec tp;
1199 if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
1200 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
1201 // yes, monotonic clock is supported
1202 _clock_gettime = clock_gettime_func;
1203 return;
1204 } else {
1205 // close librt if there is no monotonic clock
1206 dlclose(handle);
1207 }
1208 }
1209 }
1210 warning("No monotonic clock was available - timed services may " \
1211 "be adversely affected if the time-of-day clock changes");
1212 }
1213
1214 #ifndef SYS_clock_getres
1215 #if defined(X86) || defined(PPC64) || defined(S390)
1216 #define SYS_clock_getres AMD64_ONLY(229) IA32_ONLY(266) PPC64_ONLY(247) S390_ONLY(261)
1217 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1218 #else
1219 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
1220 #define sys_clock_getres(x,y) -1
1221 #endif
1222 #else
1223 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
1224 #endif
1225
1226 void os::Linux::fast_thread_clock_init() {
1227 if (!UseLinuxPosixThreadCPUClocks) {
1228 return;
1229 }
1230 clockid_t clockid;
1231 struct timespec tp;
1232 int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
1233 (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
1234
1235 // Switch to using fast clocks for thread cpu time if
1236 // the sys_clock_getres() returns 0 error code.
1749 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
1750 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
1751 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"},
1752 {EM_AARCH64, EM_AARCH64, ELFCLASS64, ELFDATA2LSB, (char*)"AARCH64"},
1753 };
1754
1755 #if (defined IA32)
1756 static Elf32_Half running_arch_code=EM_386;
1757 #elif (defined AMD64)
1758 static Elf32_Half running_arch_code=EM_X86_64;
1759 #elif (defined IA64)
1760 static Elf32_Half running_arch_code=EM_IA_64;
1761 #elif (defined __sparc) && (defined _LP64)
1762 static Elf32_Half running_arch_code=EM_SPARCV9;
1763 #elif (defined __sparc) && (!defined _LP64)
1764 static Elf32_Half running_arch_code=EM_SPARC;
1765 #elif (defined __powerpc64__)
1766 static Elf32_Half running_arch_code=EM_PPC64;
1767 #elif (defined __powerpc__)
1768 static Elf32_Half running_arch_code=EM_PPC;
1769 #elif (defined AARCH64)
1770 static Elf32_Half running_arch_code=EM_AARCH64;
1771 #elif (defined ARM) // ARM must come after AARCH64 because the closed 64-bit port requires so.
1772 static Elf32_Half running_arch_code=EM_ARM;
1773 #elif (defined S390)
1774 static Elf32_Half running_arch_code=EM_S390;
1775 #elif (defined ALPHA)
1776 static Elf32_Half running_arch_code=EM_ALPHA;
1777 #elif (defined MIPSEL)
1778 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
1779 #elif (defined PARISC)
1780 static Elf32_Half running_arch_code=EM_PARISC;
1781 #elif (defined MIPS)
1782 static Elf32_Half running_arch_code=EM_MIPS;
1783 #elif (defined M68K)
1784 static Elf32_Half running_arch_code=EM_68K;
1785 #else
1786 #error Method os::dll_load requires that one of following is defined:\
1787 AARCH64, ALPHA, ARM, AMD64, IA32, IA64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, S390, __sparc
1788 #endif
1789
1790 // Identify compatability class for VM's architecture and library's architecture
1791 // Obtain string descriptions for architectures
1792
1793 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
1794 int running_arch_index=-1;
1795
1796 for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) {
1797 if (running_arch_code == arch_array[i].code) {
1798 running_arch_index = i;
1799 }
1800 if (lib_arch.code == arch_array[i].code) {
1801 lib_arch.compat_class = arch_array[i].compat_class;
1802 lib_arch.name = arch_array[i].name;
1803 }
1804 }
1805
1806 assert(running_arch_index != -1,
1807 "Didn't find running architecture code (running_arch_code) in arch_array");
2175 }
2176 }
2177 fclose(fp);
2178 }
2179 #endif // x86 platforms
2180 return false;
2181 }
2182
2183 void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
2184 // Only print the model name if the platform provides this as a summary
2185 if (!print_model_name_and_flags(st, buf, buflen)) {
2186 st->print("\n/proc/cpuinfo:\n");
2187 if (!_print_ascii_file("/proc/cpuinfo", st)) {
2188 st->print_cr(" <Not Available>");
2189 }
2190 }
2191 }
2192
2193 #if defined(AMD64) || defined(IA32) || defined(X32)
2194 const char* search_string = "model name";
2195 #elif defined(PPC64)
2196 const char* search_string = "cpu";
2197 #elif defined(S390)
2198 const char* search_string = "processor";
2199 #elif defined(SPARC)
2200 const char* search_string = "cpu";
2201 #else
2202 const char* search_string = "Processor";
2203 #endif
2204
2205 // Parses the cpuinfo file for string representing the model name.
2206 void os::get_summary_cpu_info(char* cpuinfo, size_t length) {
2207 FILE* fp = fopen("/proc/cpuinfo", "r");
2208 if (fp != NULL) {
2209 while (!feof(fp)) {
2210 char buf[256];
2211 if (fgets(buf, sizeof(buf), fp)) {
2212 char* start = strstr(buf, search_string);
2213 if (start != NULL) {
2214 char *ptr = start + strlen(search_string);
2215 char *end = buf + strlen(buf);
2216 while (ptr != end) {
2217 // skip whitespace and colon for the rest of the name.
2218 if (*ptr != ' ' && *ptr != '\t' && *ptr != ':') {
2219 break;
2220 }
2221 ptr++;
2222 }
2223 if (ptr != end) {
2224 // reasonable string, get rid of newline and keep the rest
2225 char* nl = strchr(buf, '\n');
2226 if (nl != NULL) *nl = '\0';
2227 strncpy(cpuinfo, ptr, length);
2228 fclose(fp);
2229 return;
2230 }
2231 }
2232 }
2233 }
2234 fclose(fp);
2235 }
2236 // cpuinfo not found or parsing failed, just print generic string. The entire
2237 // /proc/cpuinfo file will be printed later in the file (or enough of it for x86)
2238 #if defined(AARCH64)
2239 strncpy(cpuinfo, "AArch64", length);
2240 #elif defined(AMD64)
2241 strncpy(cpuinfo, "x86_64", length);
2242 #elif defined(ARM) // Order wrt. AARCH64 is relevant!
2243 strncpy(cpuinfo, "ARM", length);
2244 #elif defined(IA32)
2245 strncpy(cpuinfo, "x86_32", length);
2246 #elif defined(IA64)
2247 strncpy(cpuinfo, "IA64", length);
2248 #elif defined(PPC)
2249 strncpy(cpuinfo, "PPC64", length);
2250 #elif defined(S390)
2251 strncpy(cpuinfo, "S390", length);
2252 #elif defined(SPARC)
2253 strncpy(cpuinfo, "sparcv9", length);
2254 #elif defined(ZERO_LIBARCH)
2255 strncpy(cpuinfo, ZERO_LIBARCH, length);
2256 #else
2257 strncpy(cpuinfo, "unknown", length);
2258 #endif
2259 }
2260
2261 static void print_signal_handler(outputStream* st, int sig,
2262 char* buf, size_t buflen);
2263
2264 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
2265 st->print_cr("Signal Handlers:");
2266 print_signal_handler(st, SIGSEGV, buf, buflen);
2267 print_signal_handler(st, SIGBUS , buf, buflen);
2268 print_signal_handler(st, SIGFPE , buf, buflen);
2269 print_signal_handler(st, SIGPIPE, buf, buflen);
2270 print_signal_handler(st, SIGXFSZ, buf, buflen);
2271 print_signal_handler(st, SIGILL , buf, buflen);
2272 print_signal_handler(st, SR_signum, buf, buflen);
2273 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
3229
3230 static size_t _large_page_size = 0;
3231
3232 size_t os::Linux::find_large_page_size() {
3233 size_t large_page_size = 0;
3234
3235 // large_page_size on Linux is used to round up heap size. x86 uses either
3236 // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
3237 // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
3238 // page as large as 256M.
3239 //
3240 // Here we try to figure out page size by parsing /proc/meminfo and looking
3241 // for a line with the following format:
3242 // Hugepagesize: 2048 kB
3243 //
3244 // If we can't determine the value (e.g. /proc is not mounted, or the text
3245 // format has been changed), we'll use the largest page size supported by
3246 // the processor.
3247
3248 #ifndef ZERO
3249 large_page_size =
3250 AARCH64_ONLY(2 * M)
3251 AMD64_ONLY(2 * M)
3252 ARM32_ONLY(2 * M)
3253 IA32_ONLY(4 * M)
3254 IA64_ONLY(256 * M)
3255 PPC_ONLY(4 * M)
3256 S390_ONLY(1 * M)
3257 SPARC_ONLY(4 * M);
3258 #endif // ZERO
3259
3260 FILE *fp = fopen("/proc/meminfo", "r");
3261 if (fp) {
3262 while (!feof(fp)) {
3263 int x = 0;
3264 char buf[16];
3265 if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
3266 if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
3267 large_page_size = x * K;
3268 break;
3269 }
3270 } else {
3271 // skip to next line
3272 for (;;) {
3273 int ch = fgetc(fp);
3274 if (ch == EOF || ch == (int)'\n') break;
3275 }
3276 }
3277 }
|