< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page
rev 12099 : 8166560: [s390] Basic enablement of s390 port.
Summary: Also fix problem with ARM Elf configuration.
Reviewed-by: dholmes


 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     }


< prev index next >