jdk

Форк
0
/
threadCritical_windows.cpp 
87 строк · 3.1 Кб
1
/*
2
 * Copyright (c) 2001, 2024, 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 "runtime/atomic.hpp"
27
#include "runtime/javaThread.hpp"
28
#include "runtime/threadCritical.hpp"
29

30
// OS-includes here
31
# include <windows.h>
32
# include <winbase.h>
33

34
//
35
// See threadCritical.hpp for details of this class.
36
//
37

38
static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
39
static int lock_count = 0;
40
static HANDLE lock_event;
41
static DWORD lock_owner = 0;
42

43
//
44
// Note that Microsoft's critical region code contains a race
45
// condition, and is not suitable for use. A thread holding the
46
// critical section cannot safely suspend a thread attempting
47
// to enter the critical region. The failure mode is that both
48
// threads are permanently suspended.
49
//
50
// I experiemented with the use of ordinary windows mutex objects
51
// and found them ~30 times slower than the critical region code.
52
//
53

54
static BOOL WINAPI initialize(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
55
  lock_event = CreateEvent(nullptr, false, true, nullptr);
56
  assert(lock_event != nullptr, "unexpected return value from CreateEvent");
57
  return true;
58
}
59

60
ThreadCritical::ThreadCritical() {
61
  InitOnceExecuteOnce(&initialized, &initialize, nullptr, nullptr);
62

63
  DWORD current_thread = GetCurrentThreadId();
64
  if (lock_owner != current_thread) {
65
    // Grab the lock before doing anything.
66
    DWORD ret = WaitForSingleObject(lock_event,  INFINITE);
67
    assert(ret != WAIT_FAILED,   "WaitForSingleObject failed with error code: %lu", GetLastError());
68
    assert(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with return value: %lu", ret);
69
    lock_owner = current_thread;
70
  }
71
  // Atomicity isn't required. Bump the recursion count.
72
  lock_count++;
73
}
74

75
ThreadCritical::~ThreadCritical() {
76
  assert(lock_owner == GetCurrentThreadId(), "unlock attempt by wrong thread");
77
  assert(lock_count >= 0, "Attempt to unlock when already unlocked");
78

79
  lock_count--;
80
  if (lock_count == 0) {
81
    // We're going to unlock
82
    lock_owner = 0;
83
    // No lost wakeups, lock_event stays signaled until reset.
84
    DWORD ret = SetEvent(lock_event);
85
    assert(ret != 0, "unexpected return value from SetEvent");
86
  }
87
}
88

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

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

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

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