< prev index next >

src/hotspot/os/linux/os_linux.cpp

Print this page
rev 52365 : [mq]: 8213058
rev 52366 : [mq]: 8213058-2


5939   struct stat st;
5940   int ret = os::stat(filename, &st);
5941   assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
5942   return st.st_mtim;
5943 }
5944 
5945 int os::compare_file_modified_times(const char* file1, const char* file2) {
5946   struct timespec filetime1 = get_mtime(file1);
5947   struct timespec filetime2 = get_mtime(file2);
5948   int diff = filetime1.tv_sec - filetime2.tv_sec;
5949   if (diff == 0) {
5950     return filetime1.tv_nsec - filetime2.tv_nsec;
5951   }
5952   return diff;
5953 }
5954 
5955 /////////////// Unit tests ///////////////
5956 
5957 #ifndef PRODUCT
5958 
5959 #define test_log(...)              \
5960   do {                             \
5961     if (VerboseInternalVMTests) {  \
5962       tty->print_cr(__VA_ARGS__);  \
5963       tty->flush();                \
5964     }                              \
5965   } while (false)
5966 
5967 class TestReserveMemorySpecial : AllStatic {
5968  public:
5969   static void small_page_write(void* addr, size_t size) {
5970     size_t page_size = os::vm_page_size();
5971 
5972     char* end = (char*)addr + size;
5973     for (char* p = (char*)addr; p < end; p += page_size) {
5974       *p = 1;
5975     }
5976   }
5977 
5978   static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
5979     if (!UseHugeTLBFS) {
5980       return;
5981     }
5982 
5983     test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size);
5984 
5985     char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false);
5986 
5987     if (addr != NULL) {
5988       small_page_write(addr, size);
5989 
5990       os::Linux::release_memory_special_huge_tlbfs(addr, size);
5991     }
5992   }
5993 
5994   static void test_reserve_memory_special_huge_tlbfs_only() {
5995     if (!UseHugeTLBFS) {
5996       return;
5997     }
5998 
5999     size_t lp = os::large_page_size();
6000 
6001     for (size_t size = lp; size <= lp * 10; size += lp) {
6002       test_reserve_memory_special_huge_tlbfs_only(size);
6003     }
6004   }


6023 
6024     // Pre-allocate two areas; they shall be as large as the largest allocation
6025     //  and aligned to the largest alignment we will be testing.
6026     const size_t mapping_size = sizes[num_sizes - 1] * 2;
6027     char* const mapping1 = (char*) ::mmap(NULL, mapping_size,
6028       PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
6029       -1, 0);
6030     assert(mapping1 != MAP_FAILED, "should work");
6031 
6032     char* const mapping2 = (char*) ::mmap(NULL, mapping_size,
6033       PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
6034       -1, 0);
6035     assert(mapping2 != MAP_FAILED, "should work");
6036 
6037     // Unmap the first mapping, but leave the second mapping intact: the first
6038     // mapping will serve as a value for a "good" req_addr (case 2). The second
6039     // mapping, still intact, as "bad" req_addr (case 3).
6040     ::munmap(mapping1, mapping_size);
6041 
6042     // Case 1
6043     test_log("%s, req_addr NULL:", __FUNCTION__);
6044     test_log("size            align           result");
6045 
6046     for (int i = 0; i < num_sizes; i++) {
6047       const size_t size = sizes[i];
6048       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6049         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
6050         test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " ->  " PTR_FORMAT " %s",
6051                  size, alignment, p2i(p), (p != NULL ? "" : "(failed)"));
6052         if (p != NULL) {
6053           assert(is_aligned(p, alignment), "must be");
6054           small_page_write(p, size);
6055           os::Linux::release_memory_special_huge_tlbfs(p, size);
6056         }
6057       }
6058     }
6059 
6060     // Case 2
6061     test_log("%s, req_addr non-NULL:", __FUNCTION__);
6062     test_log("size            align           req_addr         result");
6063 
6064     for (int i = 0; i < num_sizes; i++) {
6065       const size_t size = sizes[i];
6066       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6067         char* const req_addr = align_up(mapping1, alignment);
6068         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);
6069         test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " " PTR_FORMAT " ->  " PTR_FORMAT " %s",
6070                  size, alignment, p2i(req_addr), p2i(p),
6071                  ((p != NULL ? (p == req_addr ? "(exact match)" : "") : "(failed)")));
6072         if (p != NULL) {
6073           assert(p == req_addr, "must be");
6074           small_page_write(p, size);
6075           os::Linux::release_memory_special_huge_tlbfs(p, size);
6076         }
6077       }
6078     }
6079 
6080     // Case 3
6081     test_log("%s, req_addr non-NULL with preexisting mapping:", __FUNCTION__);
6082     test_log("size            align           req_addr         result");
6083 
6084     for (int i = 0; i < num_sizes; i++) {
6085       const size_t size = sizes[i];
6086       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6087         char* const req_addr = align_up(mapping2, alignment);
6088         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);
6089         test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " " PTR_FORMAT " ->  " PTR_FORMAT " %s",
6090                  size, alignment, p2i(req_addr), p2i(p), ((p != NULL ? "" : "(failed)")));
6091         // as the area around req_addr contains already existing mappings, the API should always
6092         // return NULL (as per contract, it cannot return another address)
6093         assert(p == NULL, "must be");
6094       }
6095     }
6096 
6097     ::munmap(mapping2, mapping_size);
6098 
6099   }
6100 
6101   static void test_reserve_memory_special_huge_tlbfs() {
6102     if (!UseHugeTLBFS) {
6103       return;
6104     }
6105 
6106     test_reserve_memory_special_huge_tlbfs_only();
6107     test_reserve_memory_special_huge_tlbfs_mixed();
6108   }
6109 
6110   static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
6111     if (!UseSHM) {
6112       return;
6113     }
6114 
6115     test_log("test_reserve_memory_special_shm(" SIZE_FORMAT ", " SIZE_FORMAT ")", size, alignment);
6116 
6117     char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
6118 
6119     if (addr != NULL) {
6120       assert(is_aligned(addr, alignment), "Check");
6121       assert(is_aligned(addr, os::large_page_size()), "Check");
6122 
6123       small_page_write(addr, size);
6124 
6125       os::Linux::release_memory_special_shm(addr, size);
6126     }
6127   }
6128 
6129   static void test_reserve_memory_special_shm() {
6130     size_t lp = os::large_page_size();
6131     size_t ag = os::vm_allocation_granularity();
6132 
6133     for (size_t size = ag; size < lp * 3; size += ag) {
6134       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6135         test_reserve_memory_special_shm(size, alignment);
6136       }


5939   struct stat st;
5940   int ret = os::stat(filename, &st);
5941   assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno));
5942   return st.st_mtim;
5943 }
5944 
5945 int os::compare_file_modified_times(const char* file1, const char* file2) {
5946   struct timespec filetime1 = get_mtime(file1);
5947   struct timespec filetime2 = get_mtime(file2);
5948   int diff = filetime1.tv_sec - filetime2.tv_sec;
5949   if (diff == 0) {
5950     return filetime1.tv_nsec - filetime2.tv_nsec;
5951   }
5952   return diff;
5953 }
5954 
5955 /////////////// Unit tests ///////////////
5956 
5957 #ifndef PRODUCT
5958 








5959 class TestReserveMemorySpecial : AllStatic {
5960  public:
5961   static void small_page_write(void* addr, size_t size) {
5962     size_t page_size = os::vm_page_size();
5963 
5964     char* end = (char*)addr + size;
5965     for (char* p = (char*)addr; p < end; p += page_size) {
5966       *p = 1;
5967     }
5968   }
5969 
5970   static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
5971     if (!UseHugeTLBFS) {
5972       return;
5973     }
5974 


5975     char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false);
5976 
5977     if (addr != NULL) {
5978       small_page_write(addr, size);
5979 
5980       os::Linux::release_memory_special_huge_tlbfs(addr, size);
5981     }
5982   }
5983 
5984   static void test_reserve_memory_special_huge_tlbfs_only() {
5985     if (!UseHugeTLBFS) {
5986       return;
5987     }
5988 
5989     size_t lp = os::large_page_size();
5990 
5991     for (size_t size = lp; size <= lp * 10; size += lp) {
5992       test_reserve_memory_special_huge_tlbfs_only(size);
5993     }
5994   }


6013 
6014     // Pre-allocate two areas; they shall be as large as the largest allocation
6015     //  and aligned to the largest alignment we will be testing.
6016     const size_t mapping_size = sizes[num_sizes - 1] * 2;
6017     char* const mapping1 = (char*) ::mmap(NULL, mapping_size,
6018       PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
6019       -1, 0);
6020     assert(mapping1 != MAP_FAILED, "should work");
6021 
6022     char* const mapping2 = (char*) ::mmap(NULL, mapping_size,
6023       PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
6024       -1, 0);
6025     assert(mapping2 != MAP_FAILED, "should work");
6026 
6027     // Unmap the first mapping, but leave the second mapping intact: the first
6028     // mapping will serve as a value for a "good" req_addr (case 2). The second
6029     // mapping, still intact, as "bad" req_addr (case 3).
6030     ::munmap(mapping1, mapping_size);
6031 
6032     // Case 1



6033     for (int i = 0; i < num_sizes; i++) {
6034       const size_t size = sizes[i];
6035       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6036         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);


6037         if (p != NULL) {
6038           assert(is_aligned(p, alignment), "must be");
6039           small_page_write(p, size);
6040           os::Linux::release_memory_special_huge_tlbfs(p, size);
6041         }
6042       }
6043     }
6044 
6045     // Case 2



6046     for (int i = 0; i < num_sizes; i++) {
6047       const size_t size = sizes[i];
6048       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6049         char* const req_addr = align_up(mapping1, alignment);
6050         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);



6051         if (p != NULL) {
6052           assert(p == req_addr, "must be");
6053           small_page_write(p, size);
6054           os::Linux::release_memory_special_huge_tlbfs(p, size);
6055         }
6056       }
6057     }
6058 
6059     // Case 3



6060     for (int i = 0; i < num_sizes; i++) {
6061       const size_t size = sizes[i];
6062       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6063         char* const req_addr = align_up(mapping2, alignment);
6064         char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);


6065         // as the area around req_addr contains already existing mappings, the API should always
6066         // return NULL (as per contract, it cannot return another address)
6067         assert(p == NULL, "must be");
6068       }
6069     }
6070 
6071     ::munmap(mapping2, mapping_size);
6072 
6073   }
6074 
6075   static void test_reserve_memory_special_huge_tlbfs() {
6076     if (!UseHugeTLBFS) {
6077       return;
6078     }
6079 
6080     test_reserve_memory_special_huge_tlbfs_only();
6081     test_reserve_memory_special_huge_tlbfs_mixed();
6082   }
6083 
6084   static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
6085     if (!UseSHM) {
6086       return;
6087     }
6088 


6089     char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
6090 
6091     if (addr != NULL) {
6092       assert(is_aligned(addr, alignment), "Check");
6093       assert(is_aligned(addr, os::large_page_size()), "Check");
6094 
6095       small_page_write(addr, size);
6096 
6097       os::Linux::release_memory_special_shm(addr, size);
6098     }
6099   }
6100 
6101   static void test_reserve_memory_special_shm() {
6102     size_t lp = os::large_page_size();
6103     size_t ag = os::vm_allocation_granularity();
6104 
6105     for (size_t size = ag; size < lp * 3; size += ag) {
6106       for (size_t alignment = ag; is_aligned(size, alignment); alignment *= 2) {
6107         test_reserve_memory_special_shm(size, alignment);
6108       }
< prev index next >