Top


定義場所(file name)

hotspot/src/os/solaris/vm/os_solaris.cpp

説明(description)

Solaris においては, 1 msec だけの sleep() では 他のスレッドにプロセッサ(というか lwp)が割り当たらないことがある.

このため, os::yield_all() を試みた回数を引数で渡してもらうことにし, 8 回以上失敗したら, sleep 時間を増加させることとした. さらに, それでも失敗するようなら, thr_setconcurrency() で concurrency level を増加させることにした.

// On Solaris we found that yield_all doesn't always yield to all other threads.
// There have been cases where there is a thread ready to execute but it doesn't
// get an lwp as the VM thread continues to spin with sleeps of 1 millisecond.
// The 1 millisecond wait doesn't seem long enough for the kernel to issue a
// SIGWAITING signal which will cause a new lwp to be created. So we count the
// number of times yield_all is called in the one loop and increase the sleep
// time after 8 attempts. If this fails too we increase the concurrency level
// so that the starving thread would get an lwp

名前(function name)

void os::yield_all(int attempts) {

本体部(body)

  {- -------------------------------------------
  (1) 引数で指定された失敗回数(attempts)に応じて, 以下のように yield 処理を行う.

      * 失敗回数(attempts)が 0 の場合 (初回の yield の場合):
        os::sleep() で 1msec だけ待機.
      * 失敗回数(attempts)が 25 未満の場合:
        os::sleep() で 1msec だけ待機.
      * 失敗回数(attempts)が 25 以上の場合:
        os::sleep() で 10ms だけ待機.
      * 失敗回数(attempts)が 30 に達した場合 (かつ T2 libthread ではない場合): (<= 正確には 30 の倍数に達した場合)
        thr_setconcurrency() を呼んで, LWP 数を設定.
      ---------------------------------------- -}

      // Yields to all threads, including threads with lower priorities
      if (attempts == 0) {
        os::sleep(Thread::current(), 1, false);
      } else {
        int iterations = attempts % 30;
        if (iterations == 0 && !os::Solaris::T2_libthread()) {
          // thr_setconcurrency and _getconcurrency make sense only under T1.
          int noofLWPS = thr_getconcurrency();
          if (noofLWPS < (Threads::number_of_threads() + 2)) {
            thr_setconcurrency(thr_getconcurrency() + 1);
          }
        } else if (iterations < 25) {
          os::sleep(Thread::current(), 1, false);
        } else {
          os::sleep(Thread::current(), 10, false);
        }
      }
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.