jdk

Форк
0
114 строк · 4.2 Кб
1
/*
2
 * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.
8
 *
9
 * This code is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * version 2 for more details (a copy is included in the LICENSE file that
13
 * accompanied this code).
14
 *
15
 * You should have received a copy of the GNU General Public License version
16
 * 2 along with this work; if not, write to the Free Software Foundation,
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 *
23
 */
24

25
#include "precompiled.hpp"
26
#include "memory/allocation.inline.hpp"
27
#include "nmt/memTracker.hpp"
28
#include "runtime/javaThread.hpp"
29

30
// Lifecycle management for TSM ParkEvents.
31
// ParkEvents are type-stable (TSM).
32
// In our particular implementation they happen to be immortal.
33
//
34
// We manage concurrency on the FreeList with a CAS-based
35
// detach-modify-reattach idiom that avoids the ABA problems
36
// that would otherwise be present in a simple CAS-based
37
// push-pop implementation.   (push-one and pop-all)
38
//
39
// Caveat: Allocate() and Release() may be called from threads
40
// other than the thread associated with the Event!
41
// If we need to call Allocate() when running as the thread in
42
// question then look for the PD calls to initialize native TLS.
43
// Native TLS (Win32/Linux/Solaris) can only be initialized or
44
// accessed by the associated thread.
45
// See also pd_initialize().
46
//
47
// Note that we could defer associating a ParkEvent with a thread
48
// until the 1st time the thread calls park().  unpark() calls to
49
// an unprovisioned thread would be ignored.  The first park() call
50
// for a thread would allocate and associate a ParkEvent and return
51
// immediately.
52

53
volatile int ParkEvent::ListLock = 0 ;
54
ParkEvent * volatile ParkEvent::FreeList = nullptr ;
55

56
ParkEvent * ParkEvent::Allocate (Thread * t) {
57
  ParkEvent * ev ;
58

59
  // Start by trying to recycle an existing but unassociated
60
  // ParkEvent from the global free list.
61
  // Using a spin lock since we are part of the mutex impl.
62
  // 8028280: using concurrent free list without memory management can leak
63
  // pretty badly it turns out.
64
  Thread::SpinAcquire(&ListLock, "ParkEventFreeListAllocate");
65
  {
66
    ev = FreeList;
67
    if (ev != nullptr) {
68
      FreeList = ev->FreeNext;
69
    }
70
  }
71
  Thread::SpinRelease(&ListLock);
72

73
  if (ev != nullptr) {
74
    guarantee (ev->AssociatedWith == nullptr, "invariant") ;
75
  } else {
76
    // Do this the hard way -- materialize a new ParkEvent.
77
    ev = new ParkEvent () ;
78
    guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ;
79
  }
80
  ev->reset() ;                     // courtesy to caller
81
  ev->AssociatedWith = t ;          // Associate ev with t
82
  ev->FreeNext       = nullptr ;
83
  return ev ;
84
}
85

86
void ParkEvent::Release (ParkEvent * ev) {
87
  if (ev == nullptr) return ;
88
  guarantee (ev->FreeNext == nullptr      , "invariant") ;
89
  ev->AssociatedWith = nullptr ;
90
  // Note that if we didn't have the TSM/immortal constraint, then
91
  // when reattaching we could trim the list.
92
  Thread::SpinAcquire(&ListLock, "ParkEventFreeListRelease");
93
  {
94
    ev->FreeNext = FreeList;
95
    FreeList = ev;
96
  }
97
  Thread::SpinRelease(&ListLock);
98
}
99

100
// Override operator new and delete so we can ensure that the
101
// least significant byte of ParkEvent addresses is 0.
102
// Beware that excessive address alignment is undesirable
103
// as it can result in D$ index usage imbalance as
104
// well as bank access imbalance on Niagara-like platforms,
105
// although Niagara's hash function should help.
106

107
void * ParkEvent::operator new (size_t sz) throw() {
108
  return (void *) ((intptr_t (AllocateHeap(sz + 256, mtInternal, CALLER_PC)) + 256) & -256) ;
109
}
110

111
void ParkEvent::operator delete (void * a) {
112
  // ParkEvents are type-stable and immortal ...
113
  ShouldNotReachHere();
114
}
115

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.