Mercurial > hg > graal-jvmci-8
comparison src/os/solaris/vm/os_solaris.cpp @ 11112:ec173c8f3739
Merge
author | roland |
---|---|
date | Thu, 11 Jul 2013 01:11:52 -0700 |
parents | 59b052799158 dec841e0c9aa |
children | 6b0fd0964b87 4c84d351cca9 f42f2e2a1518 |
comparison
equal
deleted
inserted
replaced
11105:22baec423e2f | 11112: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; |