src/os/solaris/vm/os_solaris.cpp

changeset 5384
dec841e0c9aa
parent 5272
1f4355cee9a2
child 5385
ec173c8f3739
equal deleted inserted replaced
5383:5f533e38e7d5 5384:dec841e0c9aa
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
2857 2792
2858 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, 2793 int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
2859 size_t alignment_hint, bool exec) { 2794 size_t alignment_hint, bool exec) {
2860 int err = Solaris::commit_memory_impl(addr, bytes, exec); 2795 int err = Solaris::commit_memory_impl(addr, bytes, exec);
2861 if (err == 0) { 2796 if (err == 0) {
2862 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { 2797 if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) {
2863 // If the large page size has been set and the VM 2798 // If the large page size has been set and the VM
2864 // is using large pages, use the large page size 2799 // is using large pages, use the large page size
2865 // if it is smaller than the alignment hint. This is 2800 // if it is smaller than the alignment hint. This is
2866 // a case where the VM wants to use a larger alignment size 2801 // a case where the VM wants to use a larger alignment size
2867 // for its own reasons but still want to use large pages 2802 // for its own reasons but still want to use large pages
2876 // for internal reasons. Try to set the mpss range using 2811 // for internal reasons. Try to set the mpss range using
2877 // the alignment_hint. 2812 // the alignment_hint.
2878 page_size = alignment_hint; 2813 page_size = alignment_hint;
2879 } 2814 }
2880 // Since this is a hint, ignore any failures. 2815 // Since this is a hint, ignore any failures.
2881 (void)Solaris::set_mpss_range(addr, bytes, page_size); 2816 (void)Solaris::setup_large_pages(addr, bytes, page_size);
2882 } 2817 }
2883 } 2818 }
2884 return err; 2819 return err;
2885 } 2820 }
2886 2821
2919 2854
2920 // Change the page size in a given range. 2855 // Change the page size in a given range.
2921 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2856 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2922 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); 2857 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
2923 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); 2858 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned.");
2924 if (UseLargePages && UseMPSS) { 2859 if (UseLargePages) {
2925 Solaris::set_mpss_range(addr, bytes, alignment_hint); 2860 Solaris::setup_large_pages(addr, bytes, alignment_hint);
2926 } 2861 }
2927 } 2862 }
2928 2863
2929 // Tell the OS to make the range local to the first-touching LWP 2864 // Tell the OS to make the range local to the first-touching LWP
2930 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { 2865 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
3319 bool os::unguard_memory(char* addr, size_t bytes) { 3254 bool os::unguard_memory(char* addr, size_t bytes) {
3320 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); 3255 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE);
3321 } 3256 }
3322 3257
3323 // Large page support 3258 // Large page support
3324
3325 // UseLargePages is the master flag to enable/disable large page memory.
3326 // UseMPSS and UseISM are supported for compatibility reasons. Their combined
3327 // effects can be described in the following table:
3328 //
3329 // UseLargePages UseMPSS UseISM
3330 // false * * => UseLargePages is the master switch, turning
3331 // it off will turn off both UseMPSS and
3332 // UseISM. VM will not use large page memory
3333 // regardless the settings of UseMPSS/UseISM.
3334 // true false false => Unless future Solaris provides other
3335 // mechanism to use large page memory, this
3336 // combination is equivalent to -UseLargePages,
3337 // VM will not use large page memory
3338 // true true false => JVM will use MPSS for large page memory.
3339 // This is the default behavior.
3340 // true false true => JVM will use ISM for large page memory.
3341 // true true true => JVM will use ISM if it is available.
3342 // Otherwise, JVM will fall back to MPSS.
3343 // Becaues ISM is now available on all
3344 // supported Solaris versions, this combination
3345 // is equivalent to +UseISM -UseMPSS.
3346
3347 static size_t _large_page_size = 0; 3259 static size_t _large_page_size = 0;
3348
3349 bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) {
3350 // x86 uses either 2M or 4M page, depending on whether PAE (Physical Address
3351 // Extensions) mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. Sparc
3352 // can support multiple page sizes.
3353
3354 // Don't bother to probe page size because getpagesizes() comes with MPSS.
3355 // ISM is only recommended on old Solaris where there is no MPSS support.
3356 // Simply choose a conservative value as default.
3357 *page_size = LargePageSizeInBytes ? LargePageSizeInBytes :
3358 SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M)
3359 ARM_ONLY(2 * M);
3360
3361 // ISM is available on all supported Solaris versions
3362 return true;
3363 }
3364 3260
3365 // Insertion sort for small arrays (descending order). 3261 // Insertion sort for small arrays (descending order).
3366 static void insertion_sort_descending(size_t* array, int len) { 3262 static void insertion_sort_descending(size_t* array, int len) {
3367 for (int i = 0; i < len; i++) { 3263 for (int i = 0; i < len; i++) {
3368 size_t val = array[i]; 3264 size_t val = array[i];
3372 array[key - 1] = tmp; 3268 array[key - 1] = tmp;
3373 } 3269 }
3374 } 3270 }
3375 } 3271 }
3376 3272
3377 bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) { 3273 bool os::Solaris::mpss_sanity_check(bool warn, size_t* page_size) {
3378 const unsigned int usable_count = VM_Version::page_size_count(); 3274 const unsigned int usable_count = VM_Version::page_size_count();
3379 if (usable_count == 1) { 3275 if (usable_count == 1) {
3380 return false; 3276 return false;
3381 } 3277 }
3382 3278
3438 trace_page_sizes("usable page sizes", _page_sizes, end + 1); 3334 trace_page_sizes("usable page sizes", _page_sizes, end + 1);
3439 return true; 3335 return true;
3440 } 3336 }
3441 3337
3442 void os::large_page_init() { 3338 void os::large_page_init() {
3443 if (!UseLargePages) { 3339 if (UseLargePages) {
3444 UseISM = false; 3340 // print a warning if any large page related flag is specified on command line
3445 UseMPSS = false; 3341 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||
3446 return; 3342 !FLAG_IS_DEFAULT(LargePageSizeInBytes);
3447 } 3343
3448 3344 UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
3449 // print a warning if any large page related flag is specified on command line 3345 }
3450 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || 3346 }
3451 !FLAG_IS_DEFAULT(UseISM) || 3347
3452 !FLAG_IS_DEFAULT(UseMPSS) || 3348 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
3453 !FLAG_IS_DEFAULT(LargePageSizeInBytes);
3454 UseISM = UseISM &&
3455 Solaris::ism_sanity_check(warn_on_failure, &_large_page_size);
3456 if (UseISM) {
3457 // ISM disables MPSS to be compatible with old JDK behavior
3458 UseMPSS = false;
3459 _page_sizes[0] = _large_page_size;
3460 _page_sizes[1] = vm_page_size();
3461 }
3462
3463 UseMPSS = UseMPSS &&
3464 Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
3465
3466 UseLargePages = UseISM || UseMPSS;
3467 }
3468
3469 bool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) {
3470 // Signal to OS that we want large pages for addresses 3349 // Signal to OS that we want large pages for addresses
3471 // from addr, addr + bytes 3350 // from addr, addr + bytes
3472 struct memcntl_mha mpss_struct; 3351 struct memcntl_mha mpss_struct;
3473 mpss_struct.mha_cmd = MHA_MAPSIZE_VA; 3352 mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
3474 mpss_struct.mha_pagesize = align; 3353 mpss_struct.mha_pagesize = align;
3475 mpss_struct.mha_flags = 0; 3354 mpss_struct.mha_flags = 0;
3476 if (memcntl(start, bytes, MC_HAT_ADVISE, 3355 // Upon successful completion, memcntl() returns 0
3477 (caddr_t) &mpss_struct, 0, 0) < 0) { 3356 if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) {
3478 debug_only(warning("Attempt to use MPSS failed.")); 3357 debug_only(warning("Attempt to use MPSS failed."));
3479 return false; 3358 return false;
3480 } 3359 }
3481 return true; 3360 return true;
3482 } 3361 }
3483 3362
3484 char* os::reserve_memory_special(size_t size, char* addr, bool exec) { 3363 char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
3485 // "exec" is passed in but not used. Creating the shared image for 3364 fatal("os::reserve_memory_special should not be called on Solaris.");
3486 // the code cache doesn't have an SHM_X executable permission to check. 3365 return NULL;
3487 assert(UseLargePages && UseISM, "only for ISM large pages");
3488
3489 char* retAddr = NULL;
3490 int shmid;
3491 key_t ismKey;
3492
3493 bool warn_on_failure = UseISM &&
3494 (!FLAG_IS_DEFAULT(UseLargePages) ||
3495 !FLAG_IS_DEFAULT(UseISM) ||
3496 !FLAG_IS_DEFAULT(LargePageSizeInBytes)
3497 );
3498 char msg[128];
3499
3500 ismKey = IPC_PRIVATE;
3501
3502 // Create a large shared memory region to attach to based on size.
3503 // Currently, size is the total size of the heap
3504 shmid = shmget(ismKey, size, SHM_R | SHM_W | IPC_CREAT);
3505 if (shmid == -1){
3506 if (warn_on_failure) {
3507 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
3508 warning(msg);
3509 }
3510 return NULL;
3511 }
3512
3513 // Attach to the region
3514 retAddr = (char *) shmat(shmid, 0, SHM_SHARE_MMU | SHM_R | SHM_W);
3515 int err = errno;
3516
3517 // Remove shmid. If shmat() is successful, the actual shared memory segment
3518 // will be deleted when it's detached by shmdt() or when the process
3519 // terminates. If shmat() is not successful this will remove the shared
3520 // segment immediately.
3521 shmctl(shmid, IPC_RMID, NULL);
3522
3523 if (retAddr == (char *) -1) {
3524 if (warn_on_failure) {
3525 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
3526 warning(msg);
3527 }
3528 return NULL;
3529 }
3530 if ((retAddr != NULL) && UseNUMAInterleaving) {
3531 numa_make_global(retAddr, size);
3532 }
3533
3534 // The memory is committed
3535 MemTracker::record_virtual_memory_reserve_and_commit((address)retAddr, size, mtNone, CURRENT_PC);
3536
3537 return retAddr;
3538 } 3366 }
3539 3367
3540 bool os::release_memory_special(char* base, size_t bytes) { 3368 bool os::release_memory_special(char* base, size_t bytes) {
3541 MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); 3369 fatal("os::release_memory_special should not be called on Solaris.");
3542 // detaching the SHM segment will also delete it, see reserve_memory_special() 3370 return false;
3543 int rslt = shmdt(base);
3544 if (rslt == 0) {
3545 tkr.record((address)base, bytes);
3546 return true;
3547 } else {
3548 tkr.discard();
3549 return false;
3550 }
3551 } 3371 }
3552 3372
3553 size_t os::large_page_size() { 3373 size_t os::large_page_size() {
3554 return _large_page_size; 3374 return _large_page_size;
3555 } 3375 }
3556 3376
3557 // MPSS allows application to commit large page memory on demand; with ISM 3377 // MPSS allows application to commit large page memory on demand; with ISM
3558 // the entire memory region must be allocated as shared memory. 3378 // the entire memory region must be allocated as shared memory.
3559 bool os::can_commit_large_page_memory() { 3379 bool os::can_commit_large_page_memory() {
3560 return UseISM ? false : true; 3380 return true;
3561 } 3381 }
3562 3382
3563 bool os::can_execute_large_page_memory() { 3383 bool os::can_execute_large_page_memory() {
3564 return UseISM ? false : true; 3384 return true;
3565 } 3385 }
3566 3386
3567 static int os_sleep(jlong millis, bool interruptible) { 3387 static int os_sleep(jlong millis, bool interruptible) {
3568 const jlong limit = INT_MAX; 3388 const jlong limit = INT_MAX;
3569 jlong prevtime; 3389 jlong prevtime;
3833 static bool priocntl_enable = false; 3653 static bool priocntl_enable = false;
3834 3654
3835 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4 3655 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
3836 static int java_MaxPriority_to_os_priority = 0; // Saved mapping 3656 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
3837 3657
3838 // Call the version of priocntl suitable for all supported versions
3839 // of Solaris. We need to call through this wrapper so that we can
3840 // build on Solaris 9 and run on Solaris 8, 9 and 10.
3841 //
3842 // This code should be removed if we ever stop supporting Solaris 8
3843 // and earlier releases.
3844
3845 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3846 typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3847 static priocntl_type priocntl_ptr = priocntl_stub;
3848
3849 // Stub to set the value of the real pointer, and then call the real
3850 // function.
3851
3852 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) {
3853 // Try Solaris 8- name only.
3854 priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl");
3855 guarantee(tmp != NULL, "priocntl function not found.");
3856 priocntl_ptr = tmp;
3857 return (*priocntl_ptr)(PC_VERSION, idtype, id, cmd, arg);
3858 }
3859
3860 3658
3861 // lwp_priocntl_init 3659 // lwp_priocntl_init
3862 // 3660 //
3863 // Try to determine the priority scale for our process. 3661 // Try to determine the priority scale for our process.
3864 // 3662 //
3865 // Return errno or 0 if OK. 3663 // Return errno or 0 if OK.
3866 // 3664 //
3867 static 3665 static int lwp_priocntl_init () {
3868 int lwp_priocntl_init ()
3869 {
3870 int rslt; 3666 int rslt;
3871 pcinfo_t ClassInfo; 3667 pcinfo_t ClassInfo;
3872 pcparms_t ParmInfo; 3668 pcparms_t ParmInfo;
3873 int i; 3669 int i;
3874 3670
3904 // the system. We should have a loop that iterates over the 3700 // the system. We should have a loop that iterates over the
3905 // classID values, which are known to be "small" integers. 3701 // classID values, which are known to be "small" integers.
3906 3702
3907 strcpy(ClassInfo.pc_clname, "TS"); 3703 strcpy(ClassInfo.pc_clname, "TS");
3908 ClassInfo.pc_cid = -1; 3704 ClassInfo.pc_cid = -1;
3909 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3705 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3910 if (rslt < 0) return errno; 3706 if (rslt < 0) return errno;
3911 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); 3707 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3912 tsLimits.schedPolicy = ClassInfo.pc_cid; 3708 tsLimits.schedPolicy = ClassInfo.pc_cid;
3913 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri; 3709 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3914 tsLimits.minPrio = -tsLimits.maxPrio; 3710 tsLimits.minPrio = -tsLimits.maxPrio;
3915 3711
3916 strcpy(ClassInfo.pc_clname, "IA"); 3712 strcpy(ClassInfo.pc_clname, "IA");
3917 ClassInfo.pc_cid = -1; 3713 ClassInfo.pc_cid = -1;
3918 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3714 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3919 if (rslt < 0) return errno; 3715 if (rslt < 0) return errno;
3920 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); 3716 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
3921 iaLimits.schedPolicy = ClassInfo.pc_cid; 3717 iaLimits.schedPolicy = ClassInfo.pc_cid;
3922 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri; 3718 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
3923 iaLimits.minPrio = -iaLimits.maxPrio; 3719 iaLimits.minPrio = -iaLimits.maxPrio;
3924 3720
3925 strcpy(ClassInfo.pc_clname, "RT"); 3721 strcpy(ClassInfo.pc_clname, "RT");
3926 ClassInfo.pc_cid = -1; 3722 ClassInfo.pc_cid = -1;
3927 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3723 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3928 if (rslt < 0) return errno; 3724 if (rslt < 0) return errno;
3929 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); 3725 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
3930 rtLimits.schedPolicy = ClassInfo.pc_cid; 3726 rtLimits.schedPolicy = ClassInfo.pc_cid;
3931 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; 3727 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
3932 rtLimits.minPrio = 0; 3728 rtLimits.minPrio = 0;
3933 3729
3934 strcpy(ClassInfo.pc_clname, "FX"); 3730 strcpy(ClassInfo.pc_clname, "FX");
3935 ClassInfo.pc_cid = -1; 3731 ClassInfo.pc_cid = -1;
3936 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3732 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3937 if (rslt < 0) return errno; 3733 if (rslt < 0) return errno;
3938 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); 3734 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1");
3939 fxLimits.schedPolicy = ClassInfo.pc_cid; 3735 fxLimits.schedPolicy = ClassInfo.pc_cid;
3940 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri; 3736 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri;
3941 fxLimits.minPrio = 0; 3737 fxLimits.minPrio = 0;
3942 3738
3943 // Query our "current" scheduling class. 3739 // Query our "current" scheduling class.
3944 // This will normally be IA, TS or, rarely, FX or RT. 3740 // This will normally be IA, TS or, rarely, FX or RT.
3945 memset(&ParmInfo, 0, sizeof(ParmInfo)); 3741 memset(&ParmInfo, 0, sizeof(ParmInfo));
3946 ParmInfo.pc_cid = PC_CLNULL; 3742 ParmInfo.pc_cid = PC_CLNULL;
3947 rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); 3743 rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3948 if (rslt < 0) return errno; 3744 if (rslt < 0) return errno;
3949 myClass = ParmInfo.pc_cid; 3745 myClass = ParmInfo.pc_cid;
3950 3746
3951 // We now know our scheduling classId, get specific information 3747 // We now know our scheduling classId, get specific information
3952 // about the class. 3748 // about the class.
3953 ClassInfo.pc_cid = myClass; 3749 ClassInfo.pc_cid = myClass;
3954 ClassInfo.pc_clname[0] = 0; 3750 ClassInfo.pc_clname[0] = 0;
3955 rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); 3751 rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo);
3956 if (rslt < 0) return errno; 3752 if (rslt < 0) return errno;
3957 3753
3958 if (ThreadPriorityVerbose) { 3754 if (ThreadPriorityVerbose) {
3959 tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname); 3755 tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
3960 } 3756 }
3961 3757
3962 memset(&ParmInfo, 0, sizeof(pcparms_t)); 3758 memset(&ParmInfo, 0, sizeof(pcparms_t));
3963 ParmInfo.pc_cid = PC_CLNULL; 3759 ParmInfo.pc_cid = PC_CLNULL;
3964 rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); 3760 rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3965 if (rslt < 0) return errno; 3761 if (rslt < 0) return errno;
3966 3762
3967 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3763 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
3968 myMin = rtLimits.minPrio; 3764 myMin = rtLimits.minPrio;
3969 myMax = rtLimits.maxPrio; 3765 myMax = rtLimits.maxPrio;
4063 ThreadID, lwpid, newPrio); 3859 ThreadID, lwpid, newPrio);
4064 } 3860 }
4065 3861
4066 memset(&ParmInfo, 0, sizeof(pcparms_t)); 3862 memset(&ParmInfo, 0, sizeof(pcparms_t));
4067 ParmInfo.pc_cid = PC_CLNULL; 3863 ParmInfo.pc_cid = PC_CLNULL;
4068 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); 3864 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
4069 if (rslt < 0) return errno; 3865 if (rslt < 0) return errno;
4070 3866
4071 int cur_class = ParmInfo.pc_cid; 3867 int cur_class = ParmInfo.pc_cid;
4072 ParmInfo.pc_cid = (id_t)new_class; 3868 ParmInfo.pc_cid = (id_t)new_class;
4073 3869
4131 tty->print_cr("Unknown new scheduling class %d\n", new_class); 3927 tty->print_cr("Unknown new scheduling class %d\n", new_class);
4132 } 3928 }
4133 return EINVAL; // no clue, punt 3929 return EINVAL; // no clue, punt
4134 } 3930 }
4135 3931
4136 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); 3932 rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
4137 if (ThreadPriorityVerbose && rslt) { 3933 if (ThreadPriorityVerbose && rslt) {
4138 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); 3934 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
4139 } 3935 }
4140 if (rslt < 0) return errno; 3936 if (rslt < 0) return errno;
4141 3937
4150 3946
4151 if (!ReadBackValidate) return 0; 3947 if (!ReadBackValidate) return 0;
4152 3948
4153 memset(&ReadBack, 0, sizeof(pcparms_t)); 3949 memset(&ReadBack, 0, sizeof(pcparms_t));
4154 ReadBack.pc_cid = PC_CLNULL; 3950 ReadBack.pc_cid = PC_CLNULL;
4155 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); 3951 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
4156 assert(rslt >= 0, "priocntl failed"); 3952 assert(rslt >= 0, "priocntl failed");
4157 Actual = Expected = 0xBAD; 3953 Actual = Expected = 0xBAD;
4158 assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match"); 3954 assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
4159 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3955 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
4160 Actual = RTPRI(ReadBack)->rt_pri; 3956 Actual = RTPRI(ReadBack)->rt_pri;
5242 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) { 5038 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
5243 assert(_getisax != NULL, "_getisax not set"); 5039 assert(_getisax != NULL, "_getisax not set");
5244 return _getisax(array, n); 5040 return _getisax(array, n);
5245 } 5041 }
5246 5042
5247 // Symbol doesn't exist in Solaris 8 pset.h
5248 #ifndef PS_MYID
5249 #define PS_MYID -3
5250 #endif
5251
5252 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); 5043 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem);
5253 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem); 5044 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem);
5254 static pset_getloadavg_type pset_getloadavg_ptr = NULL; 5045 static pset_getloadavg_type pset_getloadavg_ptr = NULL;
5255 5046
5256 void init_pset_getloadavg_ptr(void) { 5047 void init_pset_getloadavg_ptr(void) {
5413 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal); 5204 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
5414 size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit); 5205 size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
5415 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal); 5206 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal);
5416 if (lgrp_num < 2) { 5207 if (lgrp_num < 2) {
5417 // There's only one locality group, disable NUMA. 5208 // There's only one locality group, disable NUMA.
5418 UseNUMA = false;
5419 }
5420 }
5421 // ISM is not compatible with the NUMA allocator - it always allocates
5422 // pages round-robin across the lgroups.
5423 if (UseNUMA && UseLargePages && UseISM) {
5424 if (!FLAG_IS_DEFAULT(UseNUMA)) {
5425 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseISM)) {
5426 UseLargePages = false;
5427 } else {
5428 warning("UseNUMA is not compatible with ISM large pages, disabling NUMA allocator");
5429 UseNUMA = false;
5430 }
5431 } else {
5432 UseNUMA = false; 5209 UseNUMA = false;
5433 } 5210 }
5434 } 5211 }
5435 if (!UseNUMA && ForceNUMA) { 5212 if (!UseNUMA && ForceNUMA) {
5436 UseNUMA = true; 5213 UseNUMA = true;

mercurial