Mercurial > hg > truffle
comparison src/os/solaris/vm/os_solaris.cpp @ 11198:1e6d5dec4a4e
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 13:20:06 +0200 |
parents | 6b0fd0964b87 |
children | cefad50507d8 |
comparison
equal
deleted
inserted
replaced
11197:3479ab380552 | 11198:1e6d5dec4a4e |
---|---|
113 #define MAX_PATH (2 * K) | 113 #define MAX_PATH (2 * K) |
114 | 114 |
115 // for timer info max values which include all bits | 115 // for timer info max values which include all bits |
116 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) | 116 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) |
117 | 117 |
118 #ifdef _GNU_SOURCE | |
119 // See bug #6514594 | |
120 extern "C" int madvise(caddr_t, size_t, int); | |
121 extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg, | |
122 int attr, int mask); | |
123 #endif //_GNU_SOURCE | |
124 | |
125 /* | |
126 MPSS Changes Start. | |
127 The JVM binary needs to be built and run on pre-Solaris 9 | |
128 systems, but the constants needed by MPSS are only in Solaris 9 | |
129 header files. They are textually replicated here to allow | |
130 building on earlier systems. Once building on Solaris 8 is | |
131 no longer a requirement, these #defines can be replaced by ordinary | |
132 system .h inclusion. | |
133 | |
134 In earlier versions of the JDK and Solaris, we used ISM for large pages. | |
135 But ISM requires shared memory to achieve this and thus has many caveats. | |
136 MPSS is a fully transparent and is a cleaner way to get large pages. | |
137 Although we still require keeping ISM for backward compatiblitiy as well as | |
138 giving the opportunity to use large pages on older systems it is | |
139 recommended that MPSS be used for Solaris 9 and above. | |
140 | |
141 */ | |
142 | |
143 #ifndef MC_HAT_ADVISE | |
144 | |
145 struct memcntl_mha { | |
146 uint_t mha_cmd; /* command(s) */ | |
147 uint_t mha_flags; | |
148 size_t mha_pagesize; | |
149 }; | |
150 #define MC_HAT_ADVISE 7 /* advise hat map size */ | |
151 #define MHA_MAPSIZE_VA 0x1 /* set preferred page size */ | |
152 #define MAP_ALIGN 0x200 /* addr specifies alignment */ | |
153 | |
154 #endif | |
155 // MPSS Changes End. | |
156 | |
157 | 118 |
158 // Here are some liblgrp types from sys/lgrp_user.h to be able to | 119 // Here are some liblgrp types from sys/lgrp_user.h to be able to |
159 // compile on older systems without this header file. | 120 // compile on older systems without this header file. |
160 | 121 |
161 #ifndef MADV_ACCESS_LWP | 122 #ifndef MADV_ACCESS_LWP |
168 #ifndef LGRP_RSRC_CPU | 129 #ifndef LGRP_RSRC_CPU |
169 # define LGRP_RSRC_CPU 0 /* CPU resources */ | 130 # define LGRP_RSRC_CPU 0 /* CPU resources */ |
170 #endif | 131 #endif |
171 #ifndef LGRP_RSRC_MEM | 132 #ifndef LGRP_RSRC_MEM |
172 # define LGRP_RSRC_MEM 1 /* memory resources */ | 133 # define LGRP_RSRC_MEM 1 /* memory resources */ |
173 #endif | |
174 | |
175 // Some more macros from sys/mman.h that are not present in Solaris 8. | |
176 | |
177 #ifndef MAX_MEMINFO_CNT | |
178 /* | |
179 * info_req request type definitions for meminfo | |
180 * request types starting with MEMINFO_V are used for Virtual addresses | |
181 * and should not be mixed with MEMINFO_PLGRP which is targeted for Physical | |
182 * addresses | |
183 */ | |
184 # define MEMINFO_SHIFT 16 | |
185 # define MEMINFO_MASK (0xFF << MEMINFO_SHIFT) | |
186 # define MEMINFO_VPHYSICAL (0x01 << MEMINFO_SHIFT) /* get physical addr */ | |
187 # define MEMINFO_VLGRP (0x02 << MEMINFO_SHIFT) /* get lgroup */ | |
188 # define MEMINFO_VPAGESIZE (0x03 << MEMINFO_SHIFT) /* size of phys page */ | |
189 # define MEMINFO_VREPLCNT (0x04 << MEMINFO_SHIFT) /* no. of replica */ | |
190 # define MEMINFO_VREPL (0x05 << MEMINFO_SHIFT) /* physical replica */ | |
191 # define MEMINFO_VREPL_LGRP (0x06 << MEMINFO_SHIFT) /* lgrp of replica */ | |
192 # define MEMINFO_PLGRP (0x07 << MEMINFO_SHIFT) /* lgroup for paddr */ | |
193 | |
194 /* maximum number of addresses meminfo() can process at a time */ | |
195 # define MAX_MEMINFO_CNT 256 | |
196 | |
197 /* maximum number of request types */ | |
198 # define MAX_MEMINFO_REQ 31 | |
199 #endif | 134 #endif |
200 | 135 |
201 // see thr_setprio(3T) for the basis of these numbers | 136 // see thr_setprio(3T) for the basis of these numbers |
202 #define MinimumPriority 0 | 137 #define MinimumPriority 0 |
203 #define NormalPriority 64 | 138 #define NormalPriority 64 |
1922 bool os::address_is_in_vm(address addr) { | 1857 bool os::address_is_in_vm(address addr) { |
1923 static address libjvm_base_addr; | 1858 static address libjvm_base_addr; |
1924 Dl_info dlinfo; | 1859 Dl_info dlinfo; |
1925 | 1860 |
1926 if (libjvm_base_addr == NULL) { | 1861 if (libjvm_base_addr == NULL) { |
1927 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); | 1862 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { |
1928 libjvm_base_addr = (address)dlinfo.dli_fbase; | 1863 libjvm_base_addr = (address)dlinfo.dli_fbase; |
1864 } | |
1929 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); | 1865 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); |
1930 } | 1866 } |
1931 | 1867 |
1932 if (dladdr((void *)addr, &dlinfo)) { | 1868 if (dladdr((void *)addr, &dlinfo) != 0) { |
1933 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; | 1869 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; |
1934 } | 1870 } |
1935 | 1871 |
1936 return false; | 1872 return false; |
1937 } | 1873 } |
1939 typedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int); | 1875 typedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int); |
1940 static dladdr1_func_type dladdr1_func = NULL; | 1876 static dladdr1_func_type dladdr1_func = NULL; |
1941 | 1877 |
1942 bool os::dll_address_to_function_name(address addr, char *buf, | 1878 bool os::dll_address_to_function_name(address addr, char *buf, |
1943 int buflen, int * offset) { | 1879 int buflen, int * offset) { |
1880 // buf is not optional, but offset is optional | |
1881 assert(buf != NULL, "sanity check"); | |
1882 | |
1944 Dl_info dlinfo; | 1883 Dl_info dlinfo; |
1945 | 1884 |
1946 // dladdr1_func was initialized in os::init() | 1885 // dladdr1_func was initialized in os::init() |
1947 if (dladdr1_func){ | 1886 if (dladdr1_func != NULL) { |
1948 // yes, we have dladdr1 | 1887 // yes, we have dladdr1 |
1949 | 1888 |
1950 // Support for dladdr1 is checked at runtime; it may be | 1889 // Support for dladdr1 is checked at runtime; it may be |
1951 // available even if the vm is built on a machine that does | 1890 // available even if the vm is built on a machine that does |
1952 // not have dladdr1 support. Make sure there is a value for | 1891 // not have dladdr1 support. Make sure there is a value for |
1953 // RTLD_DL_SYMENT. | 1892 // RTLD_DL_SYMENT. |
1954 #ifndef RTLD_DL_SYMENT | 1893 #ifndef RTLD_DL_SYMENT |
1955 #define RTLD_DL_SYMENT 1 | 1894 #define RTLD_DL_SYMENT 1 |
1956 #endif | 1895 #endif |
1957 #ifdef _LP64 | 1896 #ifdef _LP64 |
1958 Elf64_Sym * info; | 1897 Elf64_Sym * info; |
1959 #else | 1898 #else |
1960 Elf32_Sym * info; | 1899 Elf32_Sym * info; |
1961 #endif | 1900 #endif |
1962 if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, | 1901 if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, |
1963 RTLD_DL_SYMENT)) { | 1902 RTLD_DL_SYMENT) != 0) { |
1964 if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { | 1903 // see if we have a matching symbol that covers our address |
1965 if (buf != NULL) { | 1904 if (dlinfo.dli_saddr != NULL && |
1966 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) | 1905 (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { |
1967 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); | 1906 if (dlinfo.dli_sname != NULL) { |
1968 } | 1907 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { |
1969 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; | 1908 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); |
1970 return true; | 1909 } |
1971 } | 1910 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; |
1972 } | |
1973 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { | |
1974 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), | |
1975 buf, buflen, offset, dlinfo.dli_fname)) { | |
1976 return true; | 1911 return true; |
1977 } | 1912 } |
1978 } | 1913 } |
1979 if (buf != NULL) buf[0] = '\0'; | 1914 // no matching symbol so try for just file info |
1980 if (offset != NULL) *offset = -1; | 1915 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { |
1981 return false; | |
1982 } else { | |
1983 // no, only dladdr is available | |
1984 if (dladdr((void *)addr, &dlinfo)) { | |
1985 if (buf != NULL) { | |
1986 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) | |
1987 jio_snprintf(buf, buflen, dlinfo.dli_sname); | |
1988 } | |
1989 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; | |
1990 return true; | |
1991 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { | |
1992 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), | 1916 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), |
1993 buf, buflen, offset, dlinfo.dli_fname)) { | 1917 buf, buflen, offset, dlinfo.dli_fname)) { |
1994 return true; | 1918 return true; |
1995 } | 1919 } |
1996 } | 1920 } |
1997 if (buf != NULL) buf[0] = '\0'; | 1921 } |
1998 if (offset != NULL) *offset = -1; | 1922 buf[0] = '\0'; |
1999 return false; | 1923 if (offset != NULL) *offset = -1; |
2000 } | 1924 return false; |
1925 } | |
1926 | |
1927 // no, only dladdr is available | |
1928 if (dladdr((void *)addr, &dlinfo) != 0) { | |
1929 // see if we have a matching symbol | |
1930 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { | |
1931 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { | |
1932 jio_snprintf(buf, buflen, dlinfo.dli_sname); | |
1933 } | |
1934 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; | |
1935 return true; | |
1936 } | |
1937 // no matching symbol so try for just file info | |
1938 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { | |
1939 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), | |
1940 buf, buflen, offset, dlinfo.dli_fname)) { | |
1941 return true; | |
1942 } | |
1943 } | |
1944 } | |
1945 buf[0] = '\0'; | |
1946 if (offset != NULL) *offset = -1; | |
1947 return false; | |
2001 } | 1948 } |
2002 | 1949 |
2003 bool os::dll_address_to_library_name(address addr, char* buf, | 1950 bool os::dll_address_to_library_name(address addr, char* buf, |
2004 int buflen, int* offset) { | 1951 int buflen, int* offset) { |
1952 // buf is not optional, but offset is optional | |
1953 assert(buf != NULL, "sanity check"); | |
1954 | |
2005 Dl_info dlinfo; | 1955 Dl_info dlinfo; |
2006 | 1956 |
2007 if (dladdr((void*)addr, &dlinfo)){ | 1957 if (dladdr((void*)addr, &dlinfo) != 0) { |
2008 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); | 1958 if (dlinfo.dli_fname != NULL) { |
2009 if (offset) *offset = addr - (address)dlinfo.dli_fbase; | 1959 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); |
2010 return true; | 1960 } |
2011 } else { | 1961 if (dlinfo.dli_fbase != NULL && offset != NULL) { |
2012 if (buf) buf[0] = '\0'; | 1962 *offset = addr - (address)dlinfo.dli_fbase; |
2013 if (offset) *offset = -1; | 1963 } |
2014 return false; | 1964 return true; |
2015 } | 1965 } |
1966 | |
1967 buf[0] = '\0'; | |
1968 if (offset) *offset = -1; | |
1969 return false; | |
2016 } | 1970 } |
2017 | 1971 |
2018 // Prints the names and full paths of all opened dynamic libraries | 1972 // Prints the names and full paths of all opened dynamic libraries |
2019 // for current process | 1973 // for current process |
2020 void os::print_dll_info(outputStream * st) { | 1974 void os::print_dll_info(outputStream * st) { |
2021 Dl_info dli; | 1975 Dl_info dli; |
2022 void *handle; | 1976 void *handle; |
2023 Link_map *map; | 1977 Link_map *map; |
2024 Link_map *p; | 1978 Link_map *p; |
2025 | 1979 |
2026 st->print_cr("Dynamic libraries:"); st->flush(); | 1980 st->print_cr("Dynamic libraries:"); st->flush(); |
2027 | 1981 |
2028 if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) { | 1982 if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 || |
2029 st->print_cr("Error: Cannot print dynamic libraries."); | 1983 dli.dli_fname == NULL) { |
2030 return; | 1984 st->print_cr("Error: Cannot print dynamic libraries."); |
2031 } | 1985 return; |
2032 handle = dlopen(dli.dli_fname, RTLD_LAZY); | 1986 } |
2033 if (handle == NULL) { | 1987 handle = dlopen(dli.dli_fname, RTLD_LAZY); |
2034 st->print_cr("Error: Cannot print dynamic libraries."); | 1988 if (handle == NULL) { |
2035 return; | 1989 st->print_cr("Error: Cannot print dynamic libraries."); |
2036 } | 1990 return; |
2037 dlinfo(handle, RTLD_DI_LINKMAP, &map); | 1991 } |
2038 if (map == NULL) { | 1992 dlinfo(handle, RTLD_DI_LINKMAP, &map); |
2039 st->print_cr("Error: Cannot print dynamic libraries."); | 1993 if (map == NULL) { |
2040 return; | 1994 st->print_cr("Error: Cannot print dynamic libraries."); |
2041 } | 1995 return; |
2042 | 1996 } |
2043 while (map->l_prev != NULL) | 1997 |
2044 map = map->l_prev; | 1998 while (map->l_prev != NULL) |
2045 | 1999 map = map->l_prev; |
2046 while (map != NULL) { | 2000 |
2047 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); | 2001 while (map != NULL) { |
2048 map = map->l_next; | 2002 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); |
2049 } | 2003 map = map->l_next; |
2050 | 2004 } |
2051 dlclose(handle); | 2005 |
2006 dlclose(handle); | |
2052 } | 2007 } |
2053 | 2008 |
2054 // Loads .dll/.so and | 2009 // Loads .dll/.so and |
2055 // in case of error it checks if .dll/.so was built for the | 2010 // in case of error it checks if .dll/.so was built for the |
2056 // same architecture as Hotspot is running on | 2011 // same architecture as Hotspot is running on |
2473 } | 2428 } |
2474 | 2429 |
2475 Dl_info dlinfo; | 2430 Dl_info dlinfo; |
2476 int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); | 2431 int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); |
2477 assert(ret != 0, "cannot locate libjvm"); | 2432 assert(ret != 0, "cannot locate libjvm"); |
2478 realpath((char *)dlinfo.dli_fname, buf); | 2433 if (ret != 0 && dlinfo.dli_fname != NULL) { |
2434 realpath((char *)dlinfo.dli_fname, buf); | |
2435 } else { | |
2436 buf[0] = '\0'; | |
2437 return; | |
2438 } | |
2479 | 2439 |
2480 if (Arguments::created_by_gamma_launcher()) { | 2440 if (Arguments::created_by_gamma_launcher()) { |
2481 // Support for the gamma launcher. Typical value for buf is | 2441 // Support for the gamma launcher. Typical value for buf is |
2482 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at | 2442 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at |
2483 // the right place in the string, then assume we are installed in a JDK and | 2443 // the right place in the string, then assume we are installed in a JDK and |
2782 int os::vm_allocation_granularity() { | 2742 int os::vm_allocation_granularity() { |
2783 assert(page_size != -1, "must call os::init"); | 2743 assert(page_size != -1, "must call os::init"); |
2784 return page_size; | 2744 return page_size; |
2785 } | 2745 } |
2786 | 2746 |
2787 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { | 2747 static bool recoverable_mmap_error(int err) { |
2748 // See if the error is one we can let the caller handle. This | |
2749 // list of errno values comes from the Solaris mmap(2) man page. | |
2750 switch (err) { | |
2751 case EBADF: | |
2752 case EINVAL: | |
2753 case ENOTSUP: | |
2754 // let the caller deal with these errors | |
2755 return true; | |
2756 | |
2757 default: | |
2758 // Any remaining errors on this OS can cause our reserved mapping | |
2759 // to be lost. That can cause confusion where different data | |
2760 // structures think they have the same memory mapped. The worst | |
2761 // scenario is if both the VM and a library think they have the | |
2762 // same memory mapped. | |
2763 return false; | |
2764 } | |
2765 } | |
2766 | |
2767 static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec, | |
2768 int err) { | |
2769 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT | |
2770 ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec, | |
2771 strerror(err), err); | |
2772 } | |
2773 | |
2774 static void warn_fail_commit_memory(char* addr, size_t bytes, | |
2775 size_t alignment_hint, bool exec, | |
2776 int err) { | |
2777 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT | |
2778 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes, | |
2779 alignment_hint, exec, strerror(err), err); | |
2780 } | |
2781 | |
2782 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) { | |
2788 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | 2783 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
2789 size_t size = bytes; | 2784 size_t size = bytes; |
2790 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); | 2785 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); |
2791 if (res != NULL) { | 2786 if (res != NULL) { |
2792 if (UseNUMAInterleaving) { | 2787 if (UseNUMAInterleaving) { |
2793 numa_make_global(addr, bytes); | 2788 numa_make_global(addr, bytes); |
2794 } | 2789 } |
2795 return true; | 2790 return 0; |
2796 } | 2791 } |
2797 return false; | 2792 |
2798 } | 2793 int err = errno; // save errno from mmap() call in mmap_chunk() |
2799 | 2794 |
2800 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, | 2795 if (!recoverable_mmap_error(err)) { |
2801 bool exec) { | 2796 warn_fail_commit_memory(addr, bytes, exec, err); |
2802 if (commit_memory(addr, bytes, exec)) { | 2797 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory."); |
2803 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { | 2798 } |
2799 | |
2800 return err; | |
2801 } | |
2802 | |
2803 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { | |
2804 return Solaris::commit_memory_impl(addr, bytes, exec) == 0; | |
2805 } | |
2806 | |
2807 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec, | |
2808 const char* mesg) { | |
2809 assert(mesg != NULL, "mesg must be specified"); | |
2810 int err = os::Solaris::commit_memory_impl(addr, bytes, exec); | |
2811 if (err != 0) { | |
2812 // the caller wants all commit errors to exit with the specified mesg: | |
2813 warn_fail_commit_memory(addr, bytes, exec, err); | |
2814 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg); | |
2815 } | |
2816 } | |
2817 | |
2818 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, | |
2819 size_t alignment_hint, bool exec) { | |
2820 int err = Solaris::commit_memory_impl(addr, bytes, exec); | |
2821 if (err == 0) { | |
2822 if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) { | |
2804 // If the large page size has been set and the VM | 2823 // If the large page size has been set and the VM |
2805 // is using large pages, use the large page size | 2824 // is using large pages, use the large page size |
2806 // if it is smaller than the alignment hint. This is | 2825 // if it is smaller than the alignment hint. This is |
2807 // a case where the VM wants to use a larger alignment size | 2826 // a case where the VM wants to use a larger alignment size |
2808 // for its own reasons but still want to use large pages | 2827 // for its own reasons but still want to use large pages |
2817 // for internal reasons. Try to set the mpss range using | 2836 // for internal reasons. Try to set the mpss range using |
2818 // the alignment_hint. | 2837 // the alignment_hint. |
2819 page_size = alignment_hint; | 2838 page_size = alignment_hint; |
2820 } | 2839 } |
2821 // Since this is a hint, ignore any failures. | 2840 // Since this is a hint, ignore any failures. |
2822 (void)Solaris::set_mpss_range(addr, bytes, page_size); | 2841 (void)Solaris::setup_large_pages(addr, bytes, page_size); |
2823 } | 2842 } |
2824 return true; | 2843 } |
2825 } | 2844 return err; |
2826 return false; | 2845 } |
2846 | |
2847 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, | |
2848 bool exec) { | |
2849 return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0; | |
2850 } | |
2851 | |
2852 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, | |
2853 size_t alignment_hint, bool exec, | |
2854 const char* mesg) { | |
2855 assert(mesg != NULL, "mesg must be specified"); | |
2856 int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec); | |
2857 if (err != 0) { | |
2858 // the caller wants all commit errors to exit with the specified mesg: | |
2859 warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err); | |
2860 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg); | |
2861 } | |
2827 } | 2862 } |
2828 | 2863 |
2829 // Uncommit the pages in a specified region. | 2864 // Uncommit the pages in a specified region. |
2830 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { | 2865 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { |
2831 if (madvise(addr, bytes, MADV_FREE) < 0) { | 2866 if (madvise(addr, bytes, MADV_FREE) < 0) { |
2833 return; | 2868 return; |
2834 } | 2869 } |
2835 } | 2870 } |
2836 | 2871 |
2837 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { | 2872 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { |
2838 return os::commit_memory(addr, size); | 2873 return os::commit_memory(addr, size, !ExecMem); |
2839 } | 2874 } |
2840 | 2875 |
2841 bool os::remove_stack_guard_pages(char* addr, size_t size) { | 2876 bool os::remove_stack_guard_pages(char* addr, size_t size) { |
2842 return os::uncommit_memory(addr, size); | 2877 return os::uncommit_memory(addr, size); |
2843 } | 2878 } |
2844 | 2879 |
2845 // Change the page size in a given range. | 2880 // Change the page size in a given range. |
2846 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { | 2881 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
2847 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); | 2882 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); |
2848 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); | 2883 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); |
2849 if (UseLargePages && UseMPSS) { | 2884 if (UseLargePages) { |
2850 Solaris::set_mpss_range(addr, bytes, alignment_hint); | 2885 Solaris::setup_large_pages(addr, bytes, alignment_hint); |
2851 } | 2886 } |
2852 } | 2887 } |
2853 | 2888 |
2854 // Tell the OS to make the range local to the first-touching LWP | 2889 // Tell the OS to make the range local to the first-touching LWP |
2855 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { | 2890 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { |
3244 bool os::unguard_memory(char* addr, size_t bytes) { | 3279 bool os::unguard_memory(char* addr, size_t bytes) { |
3245 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); | 3280 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); |
3246 } | 3281 } |
3247 | 3282 |
3248 // Large page support | 3283 // Large page support |
3249 | |
3250 // UseLargePages is the master flag to enable/disable large page memory. | |
3251 // UseMPSS and UseISM are supported for compatibility reasons. Their combined | |
3252 // effects can be described in the following table: | |
3253 // | |
3254 // UseLargePages UseMPSS UseISM | |
3255 // false * * => UseLargePages is the master switch, turning | |
3256 // it off will turn off both UseMPSS and | |
3257 // UseISM. VM will not use large page memory | |
3258 // regardless the settings of UseMPSS/UseISM. | |
3259 // true false false => Unless future Solaris provides other | |
3260 // mechanism to use large page memory, this | |
3261 // combination is equivalent to -UseLargePages, | |
3262 // VM will not use large page memory | |
3263 // true true false => JVM will use MPSS for large page memory. | |
3264 // This is the default behavior. | |
3265 // true false true => JVM will use ISM for large page memory. | |
3266 // true true true => JVM will use ISM if it is available. | |
3267 // Otherwise, JVM will fall back to MPSS. | |
3268 // Becaues ISM is now available on all | |
3269 // supported Solaris versions, this combination | |
3270 // is equivalent to +UseISM -UseMPSS. | |
3271 | |
3272 static size_t _large_page_size = 0; | 3284 static size_t _large_page_size = 0; |
3273 | |
3274 bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) { | |
3275 // x86 uses either 2M or 4M page, depending on whether PAE (Physical Address | |
3276 // Extensions) mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. Sparc | |
3277 // can support multiple page sizes. | |
3278 | |
3279 // Don't bother to probe page size because getpagesizes() comes with MPSS. | |
3280 // ISM is only recommended on old Solaris where there is no MPSS support. | |
3281 // Simply choose a conservative value as default. | |
3282 *page_size = LargePageSizeInBytes ? LargePageSizeInBytes : | |
3283 SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M) | |
3284 ARM_ONLY(2 * M); | |
3285 | |
3286 // ISM is available on all supported Solaris versions | |
3287 return true; | |
3288 } | |
3289 | 3285 |
3290 // Insertion sort for small arrays (descending order). | 3286 // Insertion sort for small arrays (descending order). |
3291 static void insertion_sort_descending(size_t* array, int len) { | 3287 static void insertion_sort_descending(size_t* array, int len) { |
3292 for (int i = 0; i < len; i++) { | 3288 for (int i = 0; i < len; i++) { |
3293 size_t val = array[i]; | 3289 size_t val = array[i]; |
3297 array[key - 1] = tmp; | 3293 array[key - 1] = tmp; |
3298 } | 3294 } |
3299 } | 3295 } |
3300 } | 3296 } |
3301 | 3297 |
3302 bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) { | 3298 bool os::Solaris::mpss_sanity_check(bool warn, size_t* page_size) { |
3303 const unsigned int usable_count = VM_Version::page_size_count(); | 3299 const unsigned int usable_count = VM_Version::page_size_count(); |
3304 if (usable_count == 1) { | 3300 if (usable_count == 1) { |
3305 return false; | 3301 return false; |
3306 } | 3302 } |
3307 | 3303 |
3363 trace_page_sizes("usable page sizes", _page_sizes, end + 1); | 3359 trace_page_sizes("usable page sizes", _page_sizes, end + 1); |
3364 return true; | 3360 return true; |
3365 } | 3361 } |
3366 | 3362 |
3367 void os::large_page_init() { | 3363 void os::large_page_init() { |
3368 if (!UseLargePages) { | 3364 if (UseLargePages) { |
3369 UseISM = false; | 3365 // print a warning if any large page related flag is specified on command line |
3370 UseMPSS = false; | 3366 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || |
3371 return; | 3367 !FLAG_IS_DEFAULT(LargePageSizeInBytes); |
3372 } | 3368 |
3373 | 3369 UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size); |
3374 // print a warning if any large page related flag is specified on command line | 3370 } |
3375 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || | 3371 } |
3376 !FLAG_IS_DEFAULT(UseISM) || | 3372 |
3377 !FLAG_IS_DEFAULT(UseMPSS) || | 3373 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) { |
3378 !FLAG_IS_DEFAULT(LargePageSizeInBytes); | |
3379 UseISM = UseISM && | |
3380 Solaris::ism_sanity_check(warn_on_failure, &_large_page_size); | |
3381 if (UseISM) { | |
3382 // ISM disables MPSS to be compatible with old JDK behavior | |
3383 UseMPSS = false; | |
3384 _page_sizes[0] = _large_page_size; | |
3385 _page_sizes[1] = vm_page_size(); | |
3386 } | |
3387 | |
3388 UseMPSS = UseMPSS && | |
3389 Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size); | |
3390 | |
3391 UseLargePages = UseISM || UseMPSS; | |
3392 } | |
3393 | |
3394 bool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) { | |
3395 // Signal to OS that we want large pages for addresses | 3374 // Signal to OS that we want large pages for addresses |
3396 // from addr, addr + bytes | 3375 // from addr, addr + bytes |
3397 struct memcntl_mha mpss_struct; | 3376 struct memcntl_mha mpss_struct; |
3398 mpss_struct.mha_cmd = MHA_MAPSIZE_VA; | 3377 mpss_struct.mha_cmd = MHA_MAPSIZE_VA; |
3399 mpss_struct.mha_pagesize = align; | 3378 mpss_struct.mha_pagesize = align; |
3400 mpss_struct.mha_flags = 0; | 3379 mpss_struct.mha_flags = 0; |
3401 if (memcntl(start, bytes, MC_HAT_ADVISE, | 3380 // Upon successful completion, memcntl() returns 0 |
3402 (caddr_t) &mpss_struct, 0, 0) < 0) { | 3381 if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) { |
3403 debug_only(warning("Attempt to use MPSS failed.")); | 3382 debug_only(warning("Attempt to use MPSS failed.")); |
3404 return false; | 3383 return false; |
3405 } | 3384 } |
3406 return true; | 3385 return true; |
3407 } | 3386 } |
3408 | 3387 |
3409 char* os::reserve_memory_special(size_t size, char* addr, bool exec) { | 3388 char* os::reserve_memory_special(size_t size, char* addr, bool exec) { |
3410 // "exec" is passed in but not used. Creating the shared image for | 3389 fatal("os::reserve_memory_special should not be called on Solaris."); |
3411 // the code cache doesn't have an SHM_X executable permission to check. | 3390 return NULL; |
3412 assert(UseLargePages && UseISM, "only for ISM large pages"); | |
3413 | |
3414 char* retAddr = NULL; | |
3415 int shmid; | |
3416 key_t ismKey; | |
3417 | |
3418 bool warn_on_failure = UseISM && | |
3419 (!FLAG_IS_DEFAULT(UseLargePages) || | |
3420 !FLAG_IS_DEFAULT(UseISM) || | |
3421 !FLAG_IS_DEFAULT(LargePageSizeInBytes) | |
3422 ); | |
3423 char msg[128]; | |
3424 | |
3425 ismKey = IPC_PRIVATE; | |
3426 | |
3427 // Create a large shared memory region to attach to based on size. | |
3428 // Currently, size is the total size of the heap | |
3429 shmid = shmget(ismKey, size, SHM_R | SHM_W | IPC_CREAT); | |
3430 if (shmid == -1){ | |
3431 if (warn_on_failure) { | |
3432 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); | |
3433 warning(msg); | |
3434 } | |
3435 return NULL; | |
3436 } | |
3437 | |
3438 // Attach to the region | |
3439 retAddr = (char *) shmat(shmid, 0, SHM_SHARE_MMU | SHM_R | SHM_W); | |
3440 int err = errno; | |
3441 | |
3442 // Remove shmid. If shmat() is successful, the actual shared memory segment | |
3443 // will be deleted when it's detached by shmdt() or when the process | |
3444 // terminates. If shmat() is not successful this will remove the shared | |
3445 // segment immediately. | |
3446 shmctl(shmid, IPC_RMID, NULL); | |
3447 | |
3448 if (retAddr == (char *) -1) { | |
3449 if (warn_on_failure) { | |
3450 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); | |
3451 warning(msg); | |
3452 } | |
3453 return NULL; | |
3454 } | |
3455 if ((retAddr != NULL) && UseNUMAInterleaving) { | |
3456 numa_make_global(retAddr, size); | |
3457 } | |
3458 | |
3459 // The memory is committed | |
3460 address pc = CALLER_PC; | |
3461 MemTracker::record_virtual_memory_reserve((address)retAddr, size, pc); | |
3462 MemTracker::record_virtual_memory_commit((address)retAddr, size, pc); | |
3463 | |
3464 return retAddr; | |
3465 } | 3391 } |
3466 | 3392 |
3467 bool os::release_memory_special(char* base, size_t bytes) { | 3393 bool os::release_memory_special(char* base, size_t bytes) { |
3468 // detaching the SHM segment will also delete it, see reserve_memory_special() | 3394 fatal("os::release_memory_special should not be called on Solaris."); |
3469 int rslt = shmdt(base); | 3395 return false; |
3470 if (rslt == 0) { | |
3471 MemTracker::record_virtual_memory_uncommit((address)base, bytes); | |
3472 MemTracker::record_virtual_memory_release((address)base, bytes); | |
3473 return true; | |
3474 } else { | |
3475 return false; | |
3476 } | |
3477 } | 3396 } |
3478 | 3397 |
3479 size_t os::large_page_size() { | 3398 size_t os::large_page_size() { |
3480 return _large_page_size; | 3399 return _large_page_size; |
3481 } | 3400 } |
3482 | 3401 |
3483 // MPSS allows application to commit large page memory on demand; with ISM | 3402 // MPSS allows application to commit large page memory on demand; with ISM |
3484 // the entire memory region must be allocated as shared memory. | 3403 // the entire memory region must be allocated as shared memory. |
3485 bool os::can_commit_large_page_memory() { | 3404 bool os::can_commit_large_page_memory() { |
3486 return UseISM ? false : true; | 3405 return true; |
3487 } | 3406 } |
3488 | 3407 |
3489 bool os::can_execute_large_page_memory() { | 3408 bool os::can_execute_large_page_memory() { |
3490 return UseISM ? false : true; | 3409 return true; |
3491 } | 3410 } |
3492 | 3411 |
3493 static int os_sleep(jlong millis, bool interruptible) { | 3412 static int os_sleep(jlong millis, bool interruptible) { |
3494 const jlong limit = INT_MAX; | 3413 const jlong limit = INT_MAX; |
3495 jlong prevtime; | 3414 jlong prevtime; |
3759 static bool priocntl_enable = false; | 3678 static bool priocntl_enable = false; |
3760 | 3679 |
3761 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4 | 3680 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4 |
3762 static int java_MaxPriority_to_os_priority = 0; // Saved mapping | 3681 static int java_MaxPriority_to_os_priority = 0; // Saved mapping |
3763 | 3682 |
3764 // Call the version of priocntl suitable for all supported versions | |
3765 // of Solaris. We need to call through this wrapper so that we can | |
3766 // build on Solaris 9 and run on Solaris 8, 9 and 10. | |
3767 // | |
3768 // This code should be removed if we ever stop supporting Solaris 8 | |
3769 // and earlier releases. | |
3770 | |
3771 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg); | |
3772 typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg); | |
3773 static priocntl_type priocntl_ptr = priocntl_stub; | |
3774 | |
3775 // Stub to set the value of the real pointer, and then call the real | |
3776 // function. | |
3777 | |
3778 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) { | |
3779 // Try Solaris 8- name only. | |
3780 priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl"); | |
3781 guarantee(tmp != NULL, "priocntl function not found."); | |
3782 priocntl_ptr = tmp; | |
3783 return (*priocntl_ptr)(PC_VERSION, idtype, id, cmd, arg); | |
3784 } | |
3785 | |
3786 | 3683 |
3787 // lwp_priocntl_init | 3684 // lwp_priocntl_init |
3788 // | 3685 // |
3789 // Try to determine the priority scale for our process. | 3686 // Try to determine the priority scale for our process. |
3790 // | 3687 // |
3791 // Return errno or 0 if OK. | 3688 // Return errno or 0 if OK. |
3792 // | 3689 // |
3793 static | 3690 static int lwp_priocntl_init () { |
3794 int lwp_priocntl_init () | |
3795 { | |
3796 int rslt; | 3691 int rslt; |
3797 pcinfo_t ClassInfo; | 3692 pcinfo_t ClassInfo; |
3798 pcparms_t ParmInfo; | 3693 pcparms_t ParmInfo; |
3799 int i; | 3694 int i; |
3800 | 3695 |
3830 // the system. We should have a loop that iterates over the | 3725 // the system. We should have a loop that iterates over the |
3831 // classID values, which are known to be "small" integers. | 3726 // classID values, which are known to be "small" integers. |
3832 | 3727 |
3833 strcpy(ClassInfo.pc_clname, "TS"); | 3728 strcpy(ClassInfo.pc_clname, "TS"); |
3834 ClassInfo.pc_cid = -1; | 3729 ClassInfo.pc_cid = -1; |
3835 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); | 3730 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); |
3836 if (rslt < 0) return errno; | 3731 if (rslt < 0) return errno; |
3837 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); | 3732 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); |
3838 tsLimits.schedPolicy = ClassInfo.pc_cid; | 3733 tsLimits.schedPolicy = ClassInfo.pc_cid; |
3839 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri; | 3734 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri; |
3840 tsLimits.minPrio = -tsLimits.maxPrio; | 3735 tsLimits.minPrio = -tsLimits.maxPrio; |
3841 | 3736 |
3842 strcpy(ClassInfo.pc_clname, "IA"); | 3737 strcpy(ClassInfo.pc_clname, "IA"); |
3843 ClassInfo.pc_cid = -1; | 3738 ClassInfo.pc_cid = -1; |
3844 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); | 3739 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); |
3845 if (rslt < 0) return errno; | 3740 if (rslt < 0) return errno; |
3846 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); | 3741 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); |
3847 iaLimits.schedPolicy = ClassInfo.pc_cid; | 3742 iaLimits.schedPolicy = ClassInfo.pc_cid; |
3848 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri; | 3743 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri; |
3849 iaLimits.minPrio = -iaLimits.maxPrio; | 3744 iaLimits.minPrio = -iaLimits.maxPrio; |
3850 | 3745 |
3851 strcpy(ClassInfo.pc_clname, "RT"); | 3746 strcpy(ClassInfo.pc_clname, "RT"); |
3852 ClassInfo.pc_cid = -1; | 3747 ClassInfo.pc_cid = -1; |
3853 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); | 3748 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); |
3854 if (rslt < 0) return errno; | 3749 if (rslt < 0) return errno; |
3855 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); | 3750 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); |
3856 rtLimits.schedPolicy = ClassInfo.pc_cid; | 3751 rtLimits.schedPolicy = ClassInfo.pc_cid; |
3857 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; | 3752 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; |
3858 rtLimits.minPrio = 0; | 3753 rtLimits.minPrio = 0; |
3859 | 3754 |
3860 strcpy(ClassInfo.pc_clname, "FX"); | 3755 strcpy(ClassInfo.pc_clname, "FX"); |
3861 ClassInfo.pc_cid = -1; | 3756 ClassInfo.pc_cid = -1; |
3862 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); | 3757 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); |
3863 if (rslt < 0) return errno; | 3758 if (rslt < 0) return errno; |
3864 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); | 3759 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); |
3865 fxLimits.schedPolicy = ClassInfo.pc_cid; | 3760 fxLimits.schedPolicy = ClassInfo.pc_cid; |
3866 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri; | 3761 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri; |
3867 fxLimits.minPrio = 0; | 3762 fxLimits.minPrio = 0; |
3868 | 3763 |
3869 // Query our "current" scheduling class. | 3764 // Query our "current" scheduling class. |
3870 // This will normally be IA, TS or, rarely, FX or RT. | 3765 // This will normally be IA, TS or, rarely, FX or RT. |
3871 memset(&ParmInfo, 0, sizeof(ParmInfo)); | 3766 memset(&ParmInfo, 0, sizeof(ParmInfo)); |
3872 ParmInfo.pc_cid = PC_CLNULL; | 3767 ParmInfo.pc_cid = PC_CLNULL; |
3873 rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); | 3768 rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); |
3874 if (rslt < 0) return errno; | 3769 if (rslt < 0) return errno; |
3875 myClass = ParmInfo.pc_cid; | 3770 myClass = ParmInfo.pc_cid; |
3876 | 3771 |
3877 // We now know our scheduling classId, get specific information | 3772 // We now know our scheduling classId, get specific information |
3878 // about the class. | 3773 // about the class. |
3879 ClassInfo.pc_cid = myClass; | 3774 ClassInfo.pc_cid = myClass; |
3880 ClassInfo.pc_clname[0] = 0; | 3775 ClassInfo.pc_clname[0] = 0; |
3881 rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); | 3776 rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); |
3882 if (rslt < 0) return errno; | 3777 if (rslt < 0) return errno; |
3883 | 3778 |
3884 if (ThreadPriorityVerbose) { | 3779 if (ThreadPriorityVerbose) { |
3885 tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname); | 3780 tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname); |
3886 } | 3781 } |
3887 | 3782 |
3888 memset(&ParmInfo, 0, sizeof(pcparms_t)); | 3783 memset(&ParmInfo, 0, sizeof(pcparms_t)); |
3889 ParmInfo.pc_cid = PC_CLNULL; | 3784 ParmInfo.pc_cid = PC_CLNULL; |
3890 rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); | 3785 rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); |
3891 if (rslt < 0) return errno; | 3786 if (rslt < 0) return errno; |
3892 | 3787 |
3893 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { | 3788 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { |
3894 myMin = rtLimits.minPrio; | 3789 myMin = rtLimits.minPrio; |
3895 myMax = rtLimits.maxPrio; | 3790 myMax = rtLimits.maxPrio; |
3989 ThreadID, lwpid, newPrio); | 3884 ThreadID, lwpid, newPrio); |
3990 } | 3885 } |
3991 | 3886 |
3992 memset(&ParmInfo, 0, sizeof(pcparms_t)); | 3887 memset(&ParmInfo, 0, sizeof(pcparms_t)); |
3993 ParmInfo.pc_cid = PC_CLNULL; | 3888 ParmInfo.pc_cid = PC_CLNULL; |
3994 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); | 3889 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); |
3995 if (rslt < 0) return errno; | 3890 if (rslt < 0) return errno; |
3996 | 3891 |
3997 int cur_class = ParmInfo.pc_cid; | 3892 int cur_class = ParmInfo.pc_cid; |
3998 ParmInfo.pc_cid = (id_t)new_class; | 3893 ParmInfo.pc_cid = (id_t)new_class; |
3999 | 3894 |
4057 tty->print_cr("Unknown new scheduling class %d\n", new_class); | 3952 tty->print_cr("Unknown new scheduling class %d\n", new_class); |
4058 } | 3953 } |
4059 return EINVAL; // no clue, punt | 3954 return EINVAL; // no clue, punt |
4060 } | 3955 } |
4061 | 3956 |
4062 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); | 3957 rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); |
4063 if (ThreadPriorityVerbose && rslt) { | 3958 if (ThreadPriorityVerbose && rslt) { |
4064 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); | 3959 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); |
4065 } | 3960 } |
4066 if (rslt < 0) return errno; | 3961 if (rslt < 0) return errno; |
4067 | 3962 |
4076 | 3971 |
4077 if (!ReadBackValidate) return 0; | 3972 if (!ReadBackValidate) return 0; |
4078 | 3973 |
4079 memset(&ReadBack, 0, sizeof(pcparms_t)); | 3974 memset(&ReadBack, 0, sizeof(pcparms_t)); |
4080 ReadBack.pc_cid = PC_CLNULL; | 3975 ReadBack.pc_cid = PC_CLNULL; |
4081 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); | 3976 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); |
4082 assert(rslt >= 0, "priocntl failed"); | 3977 assert(rslt >= 0, "priocntl failed"); |
4083 Actual = Expected = 0xBAD; | 3978 Actual = Expected = 0xBAD; |
4084 assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match"); | 3979 assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match"); |
4085 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { | 3980 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { |
4086 Actual = RTPRI(ReadBack)->rt_pri; | 3981 Actual = RTPRI(ReadBack)->rt_pri; |
5168 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) { | 5063 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) { |
5169 assert(_getisax != NULL, "_getisax not set"); | 5064 assert(_getisax != NULL, "_getisax not set"); |
5170 return _getisax(array, n); | 5065 return _getisax(array, n); |
5171 } | 5066 } |
5172 | 5067 |
5173 // Symbol doesn't exist in Solaris 8 pset.h | |
5174 #ifndef PS_MYID | |
5175 #define PS_MYID -3 | |
5176 #endif | |
5177 | |
5178 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); | 5068 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); |
5179 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem); | 5069 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem); |
5180 static pset_getloadavg_type pset_getloadavg_ptr = NULL; | 5070 static pset_getloadavg_type pset_getloadavg_ptr = NULL; |
5181 | 5071 |
5182 void init_pset_getloadavg_ptr(void) { | 5072 void init_pset_getloadavg_ptr(void) { |
5339 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal); | 5229 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal); |
5340 size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit); | 5230 size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit); |
5341 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal); | 5231 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal); |
5342 if (lgrp_num < 2) { | 5232 if (lgrp_num < 2) { |
5343 // There's only one locality group, disable NUMA. | 5233 // There's only one locality group, disable NUMA. |
5344 UseNUMA = false; | |
5345 } | |
5346 } | |
5347 // ISM is not compatible with the NUMA allocator - it always allocates | |
5348 // pages round-robin across the lgroups. | |
5349 if (UseNUMA && UseLargePages && UseISM) { | |
5350 if (!FLAG_IS_DEFAULT(UseNUMA)) { | |
5351 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseISM)) { | |
5352 UseLargePages = false; | |
5353 } else { | |
5354 warning("UseNUMA is not compatible with ISM large pages, disabling NUMA allocator"); | |
5355 UseNUMA = false; | |
5356 } | |
5357 } else { | |
5358 UseNUMA = false; | 5234 UseNUMA = false; |
5359 } | 5235 } |
5360 } | 5236 } |
5361 if (!UseNUMA && ForceNUMA) { | 5237 if (!UseNUMA && ForceNUMA) { |
5362 UseNUMA = true; | 5238 UseNUMA = true; |
6001 //--------------------------------------------------------------------------------- | 5877 //--------------------------------------------------------------------------------- |
6002 | 5878 |
6003 bool os::find(address addr, outputStream* st) { | 5879 bool os::find(address addr, outputStream* st) { |
6004 Dl_info dlinfo; | 5880 Dl_info dlinfo; |
6005 memset(&dlinfo, 0, sizeof(dlinfo)); | 5881 memset(&dlinfo, 0, sizeof(dlinfo)); |
6006 if (dladdr(addr, &dlinfo)) { | 5882 if (dladdr(addr, &dlinfo) != 0) { |
6007 #ifdef _LP64 | 5883 st->print(PTR_FORMAT ": ", addr); |
6008 st->print("0x%016lx: ", addr); | 5884 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { |
6009 #else | |
6010 st->print("0x%08x: ", addr); | |
6011 #endif | |
6012 if (dlinfo.dli_sname != NULL) | |
6013 st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); | 5885 st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); |
6014 else if (dlinfo.dli_fname) | 5886 } else if (dlinfo.dli_fbase != NULL) |
6015 st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); | 5887 st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); |
6016 else | 5888 else |
6017 st->print("<absolute address>"); | 5889 st->print("<absolute address>"); |
6018 if (dlinfo.dli_fname) st->print(" in %s", dlinfo.dli_fname); | 5890 if (dlinfo.dli_fname != NULL) { |
6019 #ifdef _LP64 | 5891 st->print(" in %s", dlinfo.dli_fname); |
6020 if (dlinfo.dli_fbase) st->print(" at 0x%016lx", dlinfo.dli_fbase); | 5892 } |
6021 #else | 5893 if (dlinfo.dli_fbase != NULL) { |
6022 if (dlinfo.dli_fbase) st->print(" at 0x%08x", dlinfo.dli_fbase); | 5894 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); |
6023 #endif | 5895 } |
6024 st->cr(); | 5896 st->cr(); |
6025 | 5897 |
6026 if (Verbose) { | 5898 if (Verbose) { |
6027 // decode some bytes around the PC | 5899 // decode some bytes around the PC |
6028 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size()); | 5900 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size()); |
6029 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); | 5901 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); |
6030 address lowest = (address) dlinfo.dli_sname; | 5902 address lowest = (address) dlinfo.dli_sname; |
6031 if (!lowest) lowest = (address) dlinfo.dli_fbase; | 5903 if (!lowest) lowest = (address) dlinfo.dli_fbase; |
6032 if (begin < lowest) begin = lowest; | 5904 if (begin < lowest) begin = lowest; |
6033 Dl_info dlinfo2; | 5905 Dl_info dlinfo2; |
6034 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr | 5906 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr |
6035 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) | 5907 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) |
6036 end = (address) dlinfo2.dli_saddr; | 5908 end = (address) dlinfo2.dli_saddr; |
6037 Disassembler::decode(begin, end, st); | 5909 Disassembler::decode(begin, end, st); |
6038 } | 5910 } |
6039 return true; | 5911 return true; |
6602 size_t os::write(int fd, const void *buf, unsigned int nBytes) { | 6474 size_t os::write(int fd, const void *buf, unsigned int nBytes) { |
6603 INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted); | 6475 INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted); |
6604 } | 6476 } |
6605 | 6477 |
6606 int os::close(int fd) { | 6478 int os::close(int fd) { |
6607 RESTARTABLE_RETURN_INT(::close(fd)); | 6479 return ::close(fd); |
6608 } | 6480 } |
6609 | 6481 |
6610 int os::socket_close(int fd) { | 6482 int os::socket_close(int fd) { |
6611 RESTARTABLE_RETURN_INT(::close(fd)); | 6483 return ::close(fd); |
6612 } | 6484 } |
6613 | 6485 |
6614 int os::recv(int fd, char* buf, size_t nBytes, uint flags) { | 6486 int os::recv(int fd, char* buf, size_t nBytes, uint flags) { |
6615 INTERRUPTIBLE_RETURN_INT((int)::recv(fd, buf, nBytes, flags), os::Solaris::clear_interrupted); | 6487 INTERRUPTIBLE_RETURN_INT((int)::recv(fd, buf, nBytes, flags), os::Solaris::clear_interrupted); |
6616 } | 6488 } |