src/os/solaris/vm/os_solaris.cpp

changeset 5385
ec173c8f3739
parent 5365
59b052799158
parent 5384
dec841e0c9aa
child 5578
4c84d351cca9
child 6460
f42f2e2a1518
equal deleted inserted replaced
5378:22baec423e2f 5385:ec173c8f3739
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
2882 2817
2883 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, 2818 int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
2884 size_t alignment_hint, bool exec) { 2819 size_t alignment_hint, bool exec) {
2885 int err = Solaris::commit_memory_impl(addr, bytes, exec); 2820 int err = Solaris::commit_memory_impl(addr, bytes, exec);
2886 if (err == 0) { 2821 if (err == 0) {
2887 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { 2822 if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) {
2888 // If the large page size has been set and the VM 2823 // If the large page size has been set and the VM
2889 // is using large pages, use the large page size 2824 // is using large pages, use the large page size
2890 // if it is smaller than the alignment hint. This is 2825 // if it is smaller than the alignment hint. This is
2891 // 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
2892 // for its own reasons but still want to use large pages 2827 // for its own reasons but still want to use large pages
2901 // for internal reasons. Try to set the mpss range using 2836 // for internal reasons. Try to set the mpss range using
2902 // the alignment_hint. 2837 // the alignment_hint.
2903 page_size = alignment_hint; 2838 page_size = alignment_hint;
2904 } 2839 }
2905 // Since this is a hint, ignore any failures. 2840 // Since this is a hint, ignore any failures.
2906 (void)Solaris::set_mpss_range(addr, bytes, page_size); 2841 (void)Solaris::setup_large_pages(addr, bytes, page_size);
2907 } 2842 }
2908 } 2843 }
2909 return err; 2844 return err;
2910 } 2845 }
2911 2846
2944 2879
2945 // Change the page size in a given range. 2880 // Change the page size in a given range.
2946 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) {
2947 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); 2882 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
2948 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.");
2949 if (UseLargePages && UseMPSS) { 2884 if (UseLargePages) {
2950 Solaris::set_mpss_range(addr, bytes, alignment_hint); 2885 Solaris::setup_large_pages(addr, bytes, alignment_hint);
2951 } 2886 }
2952 } 2887 }
2953 2888
2954 // 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
2955 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) {
3344 bool os::unguard_memory(char* addr, size_t bytes) { 3279 bool os::unguard_memory(char* addr, size_t bytes) {
3345 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); 3280 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE);
3346 } 3281 }
3347 3282
3348 // Large page support 3283 // Large page support
3349
3350 // UseLargePages is the master flag to enable/disable large page memory.
3351 // UseMPSS and UseISM are supported for compatibility reasons. Their combined
3352 // effects can be described in the following table:
3353 //
3354 // UseLargePages UseMPSS UseISM
3355 // false * * => UseLargePages is the master switch, turning
3356 // it off will turn off both UseMPSS and
3357 // UseISM. VM will not use large page memory
3358 // regardless the settings of UseMPSS/UseISM.
3359 // true false false => Unless future Solaris provides other
3360 // mechanism to use large page memory, this
3361 // combination is equivalent to -UseLargePages,
3362 // VM will not use large page memory
3363 // true true false => JVM will use MPSS for large page memory.
3364 // This is the default behavior.
3365 // true false true => JVM will use ISM for large page memory.
3366 // true true true => JVM will use ISM if it is available.
3367 // Otherwise, JVM will fall back to MPSS.
3368 // Becaues ISM is now available on all
3369 // supported Solaris versions, this combination
3370 // is equivalent to +UseISM -UseMPSS.
3371
3372 static size_t _large_page_size = 0; 3284 static size_t _large_page_size = 0;
3373
3374 bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) {
3375 // x86 uses either 2M or 4M page, depending on whether PAE (Physical Address
3376 // Extensions) mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. Sparc
3377 // can support multiple page sizes.
3378
3379 // Don't bother to probe page size because getpagesizes() comes with MPSS.
3380 // ISM is only recommended on old Solaris where there is no MPSS support.
3381 // Simply choose a conservative value as default.
3382 *page_size = LargePageSizeInBytes ? LargePageSizeInBytes :
3383 SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M)
3384 ARM_ONLY(2 * M);
3385
3386 // ISM is available on all supported Solaris versions
3387 return true;
3388 }
3389 3285
3390 // Insertion sort for small arrays (descending order). 3286 // Insertion sort for small arrays (descending order).
3391 static void insertion_sort_descending(size_t* array, int len) { 3287 static void insertion_sort_descending(size_t* array, int len) {
3392 for (int i = 0; i < len; i++) { 3288 for (int i = 0; i < len; i++) {
3393 size_t val = array[i]; 3289 size_t val = array[i];
3397 array[key - 1] = tmp; 3293 array[key - 1] = tmp;
3398 } 3294 }
3399 } 3295 }
3400 } 3296 }
3401 3297
3402 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) {
3403 const unsigned int usable_count = VM_Version::page_size_count(); 3299 const unsigned int usable_count = VM_Version::page_size_count();
3404 if (usable_count == 1) { 3300 if (usable_count == 1) {
3405 return false; 3301 return false;
3406 } 3302 }
3407 3303
3463 trace_page_sizes("usable page sizes", _page_sizes, end + 1); 3359 trace_page_sizes("usable page sizes", _page_sizes, end + 1);
3464 return true; 3360 return true;
3465 } 3361 }
3466 3362
3467 void os::large_page_init() { 3363 void os::large_page_init() {
3468 if (!UseLargePages) { 3364 if (UseLargePages) {
3469 UseISM = false; 3365 // print a warning if any large page related flag is specified on command line
3470 UseMPSS = false; 3366 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||
3471 return; 3367 !FLAG_IS_DEFAULT(LargePageSizeInBytes);
3472 } 3368
3473 3369 UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
3474 // print a warning if any large page related flag is specified on command line 3370 }
3475 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || 3371 }
3476 !FLAG_IS_DEFAULT(UseISM) || 3372
3477 !FLAG_IS_DEFAULT(UseMPSS) || 3373 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
3478 !FLAG_IS_DEFAULT(LargePageSizeInBytes);
3479 UseISM = UseISM &&
3480 Solaris::ism_sanity_check(warn_on_failure, &_large_page_size);
3481 if (UseISM) {
3482 // ISM disables MPSS to be compatible with old JDK behavior
3483 UseMPSS = false;
3484 _page_sizes[0] = _large_page_size;
3485 _page_sizes[1] = vm_page_size();
3486 }
3487
3488 UseMPSS = UseMPSS &&
3489 Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
3490
3491 UseLargePages = UseISM || UseMPSS;
3492 }
3493
3494 bool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) {
3495 // Signal to OS that we want large pages for addresses 3374 // Signal to OS that we want large pages for addresses
3496 // from addr, addr + bytes 3375 // from addr, addr + bytes
3497 struct memcntl_mha mpss_struct; 3376 struct memcntl_mha mpss_struct;
3498 mpss_struct.mha_cmd = MHA_MAPSIZE_VA; 3377 mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
3499 mpss_struct.mha_pagesize = align; 3378 mpss_struct.mha_pagesize = align;
3500 mpss_struct.mha_flags = 0; 3379 mpss_struct.mha_flags = 0;
3501 if (memcntl(start, bytes, MC_HAT_ADVISE, 3380 // Upon successful completion, memcntl() returns 0
3502 (caddr_t) &mpss_struct, 0, 0) < 0) { 3381 if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) {
3503 debug_only(warning("Attempt to use MPSS failed.")); 3382 debug_only(warning("Attempt to use MPSS failed."));
3504 return false; 3383 return false;
3505 } 3384 }
3506 return true; 3385 return true;
3507 } 3386 }
3508 3387
3509 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) {
3510 // "exec" is passed in but not used. Creating the shared image for 3389 fatal("os::reserve_memory_special should not be called on Solaris.");
3511 // the code cache doesn't have an SHM_X executable permission to check. 3390 return NULL;
3512 assert(UseLargePages && UseISM, "only for ISM large pages");
3513
3514 char* retAddr = NULL;
3515 int shmid;
3516 key_t ismKey;
3517
3518 bool warn_on_failure = UseISM &&
3519 (!FLAG_IS_DEFAULT(UseLargePages) ||
3520 !FLAG_IS_DEFAULT(UseISM) ||
3521 !FLAG_IS_DEFAULT(LargePageSizeInBytes)
3522 );
3523 char msg[128];
3524
3525 ismKey = IPC_PRIVATE;
3526
3527 // Create a large shared memory region to attach to based on size.
3528 // Currently, size is the total size of the heap
3529 shmid = shmget(ismKey, size, SHM_R | SHM_W | IPC_CREAT);
3530 if (shmid == -1){
3531 if (warn_on_failure) {
3532 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
3533 warning(msg);
3534 }
3535 return NULL;
3536 }
3537
3538 // Attach to the region
3539 retAddr = (char *) shmat(shmid, 0, SHM_SHARE_MMU | SHM_R | SHM_W);
3540 int err = errno;
3541
3542 // Remove shmid. If shmat() is successful, the actual shared memory segment
3543 // will be deleted when it's detached by shmdt() or when the process
3544 // terminates. If shmat() is not successful this will remove the shared
3545 // segment immediately.
3546 shmctl(shmid, IPC_RMID, NULL);
3547
3548 if (retAddr == (char *) -1) {
3549 if (warn_on_failure) {
3550 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
3551 warning(msg);
3552 }
3553 return NULL;
3554 }
3555 if ((retAddr != NULL) && UseNUMAInterleaving) {
3556 numa_make_global(retAddr, size);
3557 }
3558
3559 // The memory is committed
3560 MemTracker::record_virtual_memory_reserve_and_commit((address)retAddr, size, mtNone, CURRENT_PC);
3561
3562 return retAddr;
3563 } 3391 }
3564 3392
3565 bool os::release_memory_special(char* base, size_t bytes) { 3393 bool os::release_memory_special(char* base, size_t bytes) {
3566 MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); 3394 fatal("os::release_memory_special should not be called on Solaris.");
3567 // detaching the SHM segment will also delete it, see reserve_memory_special() 3395 return false;
3568 int rslt = shmdt(base);
3569 if (rslt == 0) {
3570 tkr.record((address)base, bytes);
3571 return true;
3572 } else {
3573 tkr.discard();
3574 return false;
3575 }
3576 } 3396 }
3577 3397
3578 size_t os::large_page_size() { 3398 size_t os::large_page_size() {
3579 return _large_page_size; 3399 return _large_page_size;
3580 } 3400 }
3581 3401
3582 // 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
3583 // the entire memory region must be allocated as shared memory. 3403 // the entire memory region must be allocated as shared memory.
3584 bool os::can_commit_large_page_memory() { 3404 bool os::can_commit_large_page_memory() {
3585 return UseISM ? false : true; 3405 return true;
3586 } 3406 }
3587 3407
3588 bool os::can_execute_large_page_memory() { 3408 bool os::can_execute_large_page_memory() {
3589 return UseISM ? false : true; 3409 return true;
3590 } 3410 }
3591 3411
3592 static int os_sleep(jlong millis, bool interruptible) { 3412 static int os_sleep(jlong millis, bool interruptible) {
3593 const jlong limit = INT_MAX; 3413 const jlong limit = INT_MAX;
3594 jlong prevtime; 3414 jlong prevtime;
3858 static bool priocntl_enable = false; 3678 static bool priocntl_enable = false;
3859 3679
3860 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
3861 static int java_MaxPriority_to_os_priority = 0; // Saved mapping 3681 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
3862 3682
3863 // Call the version of priocntl suitable for all supported versions
3864 // of Solaris. We need to call through this wrapper so that we can
3865 // build on Solaris 9 and run on Solaris 8, 9 and 10.
3866 //
3867 // This code should be removed if we ever stop supporting Solaris 8
3868 // and earlier releases.
3869
3870 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3871 typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3872 static priocntl_type priocntl_ptr = priocntl_stub;
3873
3874 // Stub to set the value of the real pointer, and then call the real
3875 // function.
3876
3877 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) {
3878 // Try Solaris 8- name only.
3879 priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl");
3880 guarantee(tmp != NULL, "priocntl function not found.");
3881 priocntl_ptr = tmp;
3882 return (*priocntl_ptr)(PC_VERSION, idtype, id, cmd, arg);
3883 }
3884
3885 3683
3886 // lwp_priocntl_init 3684 // lwp_priocntl_init
3887 // 3685 //
3888 // Try to determine the priority scale for our process. 3686 // Try to determine the priority scale for our process.
3889 // 3687 //
3890 // Return errno or 0 if OK. 3688 // Return errno or 0 if OK.
3891 // 3689 //
3892 static 3690 static int lwp_priocntl_init () {
3893 int lwp_priocntl_init ()
3894 {
3895 int rslt; 3691 int rslt;
3896 pcinfo_t ClassInfo; 3692 pcinfo_t ClassInfo;
3897 pcparms_t ParmInfo; 3693 pcparms_t ParmInfo;
3898 int i; 3694 int i;
3899 3695
3929 // the system. We should have a loop that iterates over the 3725 // the system. We should have a loop that iterates over the
3930 // classID values, which are known to be "small" integers. 3726 // classID values, which are known to be "small" integers.
3931 3727
3932 strcpy(ClassInfo.pc_clname, "TS"); 3728 strcpy(ClassInfo.pc_clname, "TS");
3933 ClassInfo.pc_cid = -1; 3729 ClassInfo.pc_cid = -1;
3934 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3730 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3935 if (rslt < 0) return errno; 3731 if (rslt < 0) return errno;
3936 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); 3732 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3937 tsLimits.schedPolicy = ClassInfo.pc_cid; 3733 tsLimits.schedPolicy = ClassInfo.pc_cid;
3938 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri; 3734 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3939 tsLimits.minPrio = -tsLimits.maxPrio; 3735 tsLimits.minPrio = -tsLimits.maxPrio;
3940 3736
3941 strcpy(ClassInfo.pc_clname, "IA"); 3737 strcpy(ClassInfo.pc_clname, "IA");
3942 ClassInfo.pc_cid = -1; 3738 ClassInfo.pc_cid = -1;
3943 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3739 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3944 if (rslt < 0) return errno; 3740 if (rslt < 0) return errno;
3945 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); 3741 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
3946 iaLimits.schedPolicy = ClassInfo.pc_cid; 3742 iaLimits.schedPolicy = ClassInfo.pc_cid;
3947 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri; 3743 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
3948 iaLimits.minPrio = -iaLimits.maxPrio; 3744 iaLimits.minPrio = -iaLimits.maxPrio;
3949 3745
3950 strcpy(ClassInfo.pc_clname, "RT"); 3746 strcpy(ClassInfo.pc_clname, "RT");
3951 ClassInfo.pc_cid = -1; 3747 ClassInfo.pc_cid = -1;
3952 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3748 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3953 if (rslt < 0) return errno; 3749 if (rslt < 0) return errno;
3954 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); 3750 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
3955 rtLimits.schedPolicy = ClassInfo.pc_cid; 3751 rtLimits.schedPolicy = ClassInfo.pc_cid;
3956 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; 3752 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
3957 rtLimits.minPrio = 0; 3753 rtLimits.minPrio = 0;
3958 3754
3959 strcpy(ClassInfo.pc_clname, "FX"); 3755 strcpy(ClassInfo.pc_clname, "FX");
3960 ClassInfo.pc_cid = -1; 3756 ClassInfo.pc_cid = -1;
3961 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3757 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3962 if (rslt < 0) return errno; 3758 if (rslt < 0) return errno;
3963 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); 3759 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1");
3964 fxLimits.schedPolicy = ClassInfo.pc_cid; 3760 fxLimits.schedPolicy = ClassInfo.pc_cid;
3965 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri; 3761 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri;
3966 fxLimits.minPrio = 0; 3762 fxLimits.minPrio = 0;
3967 3763
3968 // Query our "current" scheduling class. 3764 // Query our "current" scheduling class.
3969 // This will normally be IA, TS or, rarely, FX or RT. 3765 // This will normally be IA, TS or, rarely, FX or RT.
3970 memset(&ParmInfo, 0, sizeof(ParmInfo)); 3766 memset(&ParmInfo, 0, sizeof(ParmInfo));
3971 ParmInfo.pc_cid = PC_CLNULL; 3767 ParmInfo.pc_cid = PC_CLNULL;
3972 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);
3973 if (rslt < 0) return errno; 3769 if (rslt < 0) return errno;
3974 myClass = ParmInfo.pc_cid; 3770 myClass = ParmInfo.pc_cid;
3975 3771
3976 // We now know our scheduling classId, get specific information 3772 // We now know our scheduling classId, get specific information
3977 // about the class. 3773 // about the class.
3978 ClassInfo.pc_cid = myClass; 3774 ClassInfo.pc_cid = myClass;
3979 ClassInfo.pc_clname[0] = 0; 3775 ClassInfo.pc_clname[0] = 0;
3980 rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); 3776 rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo);
3981 if (rslt < 0) return errno; 3777 if (rslt < 0) return errno;
3982 3778
3983 if (ThreadPriorityVerbose) { 3779 if (ThreadPriorityVerbose) {
3984 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);
3985 } 3781 }
3986 3782
3987 memset(&ParmInfo, 0, sizeof(pcparms_t)); 3783 memset(&ParmInfo, 0, sizeof(pcparms_t));
3988 ParmInfo.pc_cid = PC_CLNULL; 3784 ParmInfo.pc_cid = PC_CLNULL;
3989 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);
3990 if (rslt < 0) return errno; 3786 if (rslt < 0) return errno;
3991 3787
3992 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3788 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
3993 myMin = rtLimits.minPrio; 3789 myMin = rtLimits.minPrio;
3994 myMax = rtLimits.maxPrio; 3790 myMax = rtLimits.maxPrio;
4088 ThreadID, lwpid, newPrio); 3884 ThreadID, lwpid, newPrio);
4089 } 3885 }
4090 3886
4091 memset(&ParmInfo, 0, sizeof(pcparms_t)); 3887 memset(&ParmInfo, 0, sizeof(pcparms_t));
4092 ParmInfo.pc_cid = PC_CLNULL; 3888 ParmInfo.pc_cid = PC_CLNULL;
4093 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); 3889 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
4094 if (rslt < 0) return errno; 3890 if (rslt < 0) return errno;
4095 3891
4096 int cur_class = ParmInfo.pc_cid; 3892 int cur_class = ParmInfo.pc_cid;
4097 ParmInfo.pc_cid = (id_t)new_class; 3893 ParmInfo.pc_cid = (id_t)new_class;
4098 3894
4156 tty->print_cr("Unknown new scheduling class %d\n", new_class); 3952 tty->print_cr("Unknown new scheduling class %d\n", new_class);
4157 } 3953 }
4158 return EINVAL; // no clue, punt 3954 return EINVAL; // no clue, punt
4159 } 3955 }
4160 3956
4161 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); 3957 rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
4162 if (ThreadPriorityVerbose && rslt) { 3958 if (ThreadPriorityVerbose && rslt) {
4163 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); 3959 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
4164 } 3960 }
4165 if (rslt < 0) return errno; 3961 if (rslt < 0) return errno;
4166 3962
4175 3971
4176 if (!ReadBackValidate) return 0; 3972 if (!ReadBackValidate) return 0;
4177 3973
4178 memset(&ReadBack, 0, sizeof(pcparms_t)); 3974 memset(&ReadBack, 0, sizeof(pcparms_t));
4179 ReadBack.pc_cid = PC_CLNULL; 3975 ReadBack.pc_cid = PC_CLNULL;
4180 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); 3976 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
4181 assert(rslt >= 0, "priocntl failed"); 3977 assert(rslt >= 0, "priocntl failed");
4182 Actual = Expected = 0xBAD; 3978 Actual = Expected = 0xBAD;
4183 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");
4184 if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3980 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
4185 Actual = RTPRI(ReadBack)->rt_pri; 3981 Actual = RTPRI(ReadBack)->rt_pri;
5267 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) { 5063 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
5268 assert(_getisax != NULL, "_getisax not set"); 5064 assert(_getisax != NULL, "_getisax not set");
5269 return _getisax(array, n); 5065 return _getisax(array, n);
5270 } 5066 }
5271 5067
5272 // Symbol doesn't exist in Solaris 8 pset.h
5273 #ifndef PS_MYID
5274 #define PS_MYID -3
5275 #endif
5276
5277 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); 5068 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem);
5278 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);
5279 static pset_getloadavg_type pset_getloadavg_ptr = NULL; 5070 static pset_getloadavg_type pset_getloadavg_ptr = NULL;
5280 5071
5281 void init_pset_getloadavg_ptr(void) { 5072 void init_pset_getloadavg_ptr(void) {
5438 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal); 5229 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
5439 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);
5440 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal); 5231 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal);
5441 if (lgrp_num < 2) { 5232 if (lgrp_num < 2) {
5442 // There's only one locality group, disable NUMA. 5233 // There's only one locality group, disable NUMA.
5443 UseNUMA = false;
5444 }
5445 }
5446 // ISM is not compatible with the NUMA allocator - it always allocates
5447 // pages round-robin across the lgroups.
5448 if (UseNUMA && UseLargePages && UseISM) {
5449 if (!FLAG_IS_DEFAULT(UseNUMA)) {
5450 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseISM)) {
5451 UseLargePages = false;
5452 } else {
5453 warning("UseNUMA is not compatible with ISM large pages, disabling NUMA allocator");
5454 UseNUMA = false;
5455 }
5456 } else {
5457 UseNUMA = false; 5234 UseNUMA = false;
5458 } 5235 }
5459 } 5236 }
5460 if (!UseNUMA && ForceNUMA) { 5237 if (!UseNUMA && ForceNUMA) {
5461 UseNUMA = true; 5238 UseNUMA = true;

mercurial