1
/*
2
    RawSpeed - RAW file decoder.
3

4
    Copyright (C) 2017-2018 Roman Lebedev
5

6
    This library is free software; you can redistribute it and/or
7
    modify it under the terms of the GNU Lesser General Public
8
    License as published by the Free Software Foundation; either
9
    version 2 of the License, or (at your option) any later version.
10

11
    This library is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
    Lesser General Public License for more details.
15

16
    You should have received a copy of the GNU Lesser General Public
17
    License along with this library; if not, write to the Free Software
18
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20

21
#pragma once
22

23
#include "rawspeedconfig.h"
24
#include "ThreadSafetyAnalysis.h"
25

26
#ifdef HAVE_OPENMP
27
#include <omp.h>
28
#endif
29

30
namespace rawspeed {
31

32
// Defines an annotated interface for mutexes.
33
// These methods can be implemented to use any internal mutex implementation.
34
#ifdef HAVE_OPENMP
35

36
class CAPABILITY("mutex") Mutex final {
37
  omp_lock_t mutex;
38

39
public:
40 1
  explicit Mutex() { omp_init_lock(&mutex); }
41

42
  Mutex(const Mutex&) = delete;
43
  Mutex(Mutex&&) = delete;
44
  Mutex& operator=(const Mutex&) = delete;
45
  Mutex& operator=(Mutex&&) = delete;
46

47 1
  ~Mutex() { omp_destroy_lock(&mutex); }
48

49
  // Acquire/lock this mutex exclusively.  Only one thread can have exclusive
50
  // access at any one time.  Write operations to guarded data require an
51
  // exclusive lock.
52 1
  void Lock() ACQUIRE() { omp_set_lock(&mutex); }
53

54
  // Release/unlock an exclusive mutex.
55 1
  void Unlock() RELEASE() { omp_unset_lock(&mutex); }
56

57
  // Try to acquire the mutex.  Returns true on success, and false on failure.
58
  bool TryLock() TRY_ACQUIRE(true) { return omp_test_lock(&mutex); }
59

60
  // For negative capabilities.
61
  const Mutex& operator!() const { return *this; }
62
};
63

64
#else
65

66
class CAPABILITY("mutex") Mutex final {
67
public:
68
  explicit Mutex() = default;
69

70
  Mutex(const Mutex&) = delete;
71
  Mutex(Mutex&&) = delete;
72
  Mutex& operator=(const Mutex&) = delete;
73
  Mutex& operator=(Mutex&&) = delete;
74

75
  ~Mutex() = default;
76

77
  // Acquire/lock this mutex exclusively.  Only one thread can have exclusive
78
  // access at any one time.  Write operations to guarded data require an
79
  // exclusive lock.
80
  void Lock() const ACQUIRE() {
81
    // NOP, since there is no mutex. only here to still check for proper locking
82
  }
83

84
  // Release/unlock an exclusive mutex.
85
  void Unlock() const RELEASE() {
86
    // NOP, since there is no mutex. only here to still check for proper locking
87
  }
88

89
  // Try to acquire the mutex.  Returns true on success, and false on failure.
90
  bool TryLock() const TRY_ACQUIRE(true) {
91
    // NOP, since there is no mutex. only here to still check for proper locking
92
    return true;
93
  }
94

95
  // For negative capabilities.
96
  const Mutex& operator!() const { return *this; }
97
};
98

99
#endif
100

101
// MutexLocker is an RAII class that acquires a mutex in its constructor, and
102
// releases it in its destructor.
103
class SCOPED_CAPABILITY MutexLocker final {
104
  Mutex* mut;
105

106
public:
107 1
  explicit MutexLocker(Mutex* mu) ACQUIRE(mu) : mut(mu) { mu->Lock(); }
108

109
  MutexLocker(const MutexLocker&) = delete;
110
  MutexLocker(MutexLocker&&) = delete;
111
  MutexLocker& operator=(const MutexLocker&) = delete;
112
  MutexLocker& operator=(MutexLocker&&) = delete;
113

114 1
  ~MutexLocker() RELEASE() { mut->Unlock(); }
115
};
116

117
} // namespace rawspeed

Read our documentation on viewing source code .

Loading