hotspot/src/os/aix/vm/os_aix.cpp
changeset 46576 0b817584e8a9
parent 46567 30efdd5f0dc9
child 46589 f1c04490ded1
equal deleted inserted replaced
46575:d6fb8a7a7843 46576:0b817584e8a9
   128 #define ERROR_MP_OS_TOO_OLD                          100
   128 #define ERROR_MP_OS_TOO_OLD                          100
   129 #define ERROR_MP_EXTSHM_ACTIVE                       101
   129 #define ERROR_MP_EXTSHM_ACTIVE                       101
   130 #define ERROR_MP_VMGETINFO_FAILED                    102
   130 #define ERROR_MP_VMGETINFO_FAILED                    102
   131 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
   131 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
   132 
   132 
   133 // Query dimensions of the stack of the calling thread.
       
   134 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size);
       
   135 static address resolve_function_descriptor_to_code_pointer(address p);
   133 static address resolve_function_descriptor_to_code_pointer(address p);
   136 
   134 
   137 static void vmembk_print_on(outputStream* os);
   135 static void vmembk_print_on(outputStream* os);
   138 
   136 
   139 ////////////////////////////////////////////////////////////////////////////////
   137 ////////////////////////////////////////////////////////////////////////////////
   762 static void *thread_native_entry(Thread *thread) {
   760 static void *thread_native_entry(Thread *thread) {
   763 
   761 
   764   // find out my own stack dimensions
   762   // find out my own stack dimensions
   765   {
   763   {
   766     // actually, this should do exactly the same as thread->record_stack_base_and_size...
   764     // actually, this should do exactly the same as thread->record_stack_base_and_size...
   767     address base = 0;
   765     thread->set_stack_base(os::current_stack_base());
   768     size_t size = 0;
   766     thread->set_stack_size(os::current_stack_size());
   769     query_stack_dimensions(&base, &size);
       
   770     thread->set_stack_base(base);
       
   771     thread->set_stack_size(size);
       
   772   }
   767   }
   773 
   768 
   774   const pthread_t pthread_id = ::pthread_self();
   769   const pthread_t pthread_id = ::pthread_self();
   775   const tid_t kernel_thread_id = ::thread_self();
   770   const tid_t kernel_thread_id = ::thread_self();
   776 
   771 
  4295 }
  4290 }
  4296 
  4291 
  4297 /////////////////////////////////////////////////////////////////////////////
  4292 /////////////////////////////////////////////////////////////////////////////
  4298 // thread stack
  4293 // thread stack
  4299 
  4294 
  4300 // Function to query the current stack size using pthread_getthrds_np.
       
  4301 static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size) {
       
  4302 
       
  4303   // Information about this api can be found (a) in the pthread.h header and
       
  4304   // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm
       
  4305   //
       
  4306   // The use of this API to find out the current stack is kind of undefined.
       
  4307   // But after a lot of tries and asking IBM about it, I concluded that it is safe
       
  4308   // enough for cases where I let the pthread library create its stacks. For cases
       
  4309   // where I create an own stack and pass this to pthread_create, it seems not to
       
  4310   // work (the returned stack size in that case is 0).
       
  4311 
       
  4312   pthread_t tid = pthread_self();
       
  4313   struct __pthrdsinfo pinfo;
       
  4314   char dummy[1]; // Just needed to satisfy pthread_getthrds_np.
       
  4315   int dummy_size = sizeof(dummy);
       
  4316 
       
  4317   memset(&pinfo, 0, sizeof(pinfo));
       
  4318 
       
  4319   const int rc = pthread_getthrds_np(&tid, PTHRDSINFO_QUERY_ALL, &pinfo,
       
  4320                                      sizeof(pinfo), dummy, &dummy_size);
       
  4321 
       
  4322   if (rc != 0) {
       
  4323     trcVerbose("pthread_getthrds_np failed (%d)", rc);
       
  4324     return false;
       
  4325   }
       
  4326   guarantee0(pinfo.__pi_stackend);
       
  4327 
       
  4328   // The following may happen when invoking pthread_getthrds_np on a pthread
       
  4329   // running on a user provided stack (when handing down a stack to pthread
       
  4330   // create, see pthread_attr_setstackaddr).
       
  4331   // Not sure what to do then.
       
  4332 
       
  4333   guarantee0(pinfo.__pi_stacksize);
       
  4334 
       
  4335   // Note: we get three values from pthread_getthrds_np:
       
  4336   //       __pi_stackaddr, __pi_stacksize, __pi_stackend
       
  4337   //
       
  4338   // high addr    ---------------------
       
  4339   //
       
  4340   //    |         pthread internal data, like ~2K
       
  4341   //    |
       
  4342   //    |         ---------------------   __pi_stackend   (usually not page aligned, (xxxxF890))
       
  4343   //    |
       
  4344   //    |
       
  4345   //    |
       
  4346   //    |
       
  4347   //    |
       
  4348   //    |
       
  4349   //    |          ---------------------   (__pi_stackend - __pi_stacksize)
       
  4350   //    |
       
  4351   //    |          padding to align the following AIX guard pages, if enabled.
       
  4352   //    |
       
  4353   //    V          ---------------------   __pi_stackaddr
       
  4354   //
       
  4355   // low addr      AIX guard pages, if enabled (AIXTHREAD_GUARDPAGES > 0)
       
  4356   //
       
  4357 
       
  4358   address stack_base = (address)(pinfo.__pi_stackend);
       
  4359   address stack_low_addr = (address)align_ptr_up(pinfo.__pi_stackaddr,
       
  4360     os::vm_page_size());
       
  4361   size_t stack_size = stack_base - stack_low_addr;
       
  4362 
       
  4363   if (p_stack_base) {
       
  4364     *p_stack_base = stack_base;
       
  4365   }
       
  4366 
       
  4367   if (p_stack_size) {
       
  4368     *p_stack_size = stack_size;
       
  4369   }
       
  4370 
       
  4371   return true;
       
  4372 }
       
  4373 
       
  4374 // Get the current stack base from the OS (actually, the pthread library).
  4295 // Get the current stack base from the OS (actually, the pthread library).
       
  4296 // Note: usually not page aligned.
  4375 address os::current_stack_base() {
  4297 address os::current_stack_base() {
  4376   address p;
  4298   AixMisc::stackbounds_t bounds;
  4377   query_stack_dimensions(&p, 0);
  4299   bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);
  4378   return p;
  4300   guarantee(rc, "Unable to retrieve stack bounds.");
       
  4301   return bounds.base;
  4379 }
  4302 }
  4380 
  4303 
  4381 // Get the current stack size from the OS (actually, the pthread library).
  4304 // Get the current stack size from the OS (actually, the pthread library).
       
  4305 // Returned size is such that (base - size) is always aligned to page size.
  4382 size_t os::current_stack_size() {
  4306 size_t os::current_stack_size() {
  4383   size_t s;
  4307   AixMisc::stackbounds_t bounds;
  4384   query_stack_dimensions(0, &s);
  4308   bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);
       
  4309   guarantee(rc, "Unable to retrieve stack bounds.");
       
  4310   // Align the returned stack size such that the stack low address
       
  4311   // is aligned to page size (Note: base is usually not and we do not care).
       
  4312   // We need to do this because caller code will assume stack low address is
       
  4313   // page aligned and will place guard pages without checking.
       
  4314   address low = bounds.base - bounds.size;
       
  4315   address low_aligned = (address)align_ptr_up(low, os::vm_page_size());
       
  4316   size_t s = bounds.base - low_aligned;
  4385   return s;
  4317   return s;
  4386 }
  4318 }
  4387 
  4319 
  4388 extern char** environ;
  4320 extern char** environ;
  4389 
  4321