FLANG

lock.h
1 //===-- runtime/lock.h ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // Wraps a mutex
10
11 #ifndef FORTRAN_RUNTIME_LOCK_H_
12 #define FORTRAN_RUNTIME_LOCK_H_
13
14 #include "terminator.h"
15
16 // Avoid <mutex> if possible to avoid introduction of C++ runtime
17 // library dependence.
18 #ifndef _WIN32
19 #define USE_PTHREADS 1
20 #else
21 #undef USE_PTHREADS
22 #endif
23
24 #if USE_PTHREADS
25 #include <pthread.h>
26 #else
27 #include <mutex>
28 #endif
29
30 namespace Fortran::runtime {
31
32 class Lock {
33 public:
34 #if USE_PTHREADS
35 Lock() { pthread_mutex_init(&mutex_, nullptr); }
36 ~Lock() { pthread_mutex_destroy(&mutex_); }
37 void Take() {
38 while (pthread_mutex_lock(&mutex_)) {
39 }
40 }
41 bool Try() { return pthread_mutex_trylock(&mutex_) == 0; }
42 void Drop() { pthread_mutex_unlock(&mutex_); }
43 #else
44 void Take() { mutex_.lock(); }
45 bool Try() { return mutex_.try_lock(); }
46 void Drop() { mutex_.unlock(); }
47 #endif
48
49 void CheckLocked(const Terminator &terminator) {
50 if (Try()) {
51 Drop();
52 terminator.Crash("Lock::CheckLocked() failed");
53 }
54 }
55
56 private:
57 #if USE_PTHREADS
58 pthread_mutex_t mutex_{};
59 #else
60 std::mutex mutex_;
61 #endif
62 };
63
64 class CriticalSection {
65 public:
66 explicit CriticalSection(Lock &lock) : lock_{lock} { lock_.Take(); }
67 ~CriticalSection() { lock_.Drop(); }
68
69 private:
70 Lock &lock_;
71 };
72 } // namespace Fortran::runtime
73
74 #endif // FORTRAN_RUNTIME_LOCK_H_
Fortran::runtime::Terminator
Definition: terminator.h:21
Fortran::runtime::CriticalSection
Definition: lock.h:64
Fortran::runtime::Lock
Definition: lock.h:32