blob: eed5b0b7e738d9ae0814b97041fec6776418808b [file] [log] [blame]
Brian Silvermandc1eb272014-08-19 14:25:59 -04001#include "aos/common/mutex.h"
2
3#include <inttypes.h>
4#include <stdio.h>
5#include <string.h>
6
7#include "aos/common/type_traits.h"
8#include "aos/common/logging/logging.h"
9
10namespace aos {
11
12Mutex::Mutex() : impl_() {
13 static_assert(shm_ok<Mutex>::value,
14 "Mutex is not safe for use in shared memory.");
15}
16
17Mutex::~Mutex() {
Brian Silverman1dfe48b2014-09-06 16:13:02 -040018 if (__builtin_expect(mutex_islocked(&impl_), false)) {
Brian Silvermandc1eb272014-08-19 14:25:59 -040019 LOG(FATAL, "destroying locked mutex %p (aka %p)\n",
20 this, &impl_);
21 }
22}
23
24// Lock and Unlock use the return values of mutex_lock/mutex_unlock
25// to determine whether the lock/unlock succeeded.
26
27bool Mutex::Lock() {
28 const int ret = mutex_grab(&impl_);
29 if (ret == 0) {
30 return false;
Brian Silverman71c55c52014-08-19 14:31:59 -040031 } else if (ret == 1) {
32 return true;
Brian Silvermandc1eb272014-08-19 14:25:59 -040033 } else {
34 LOG(FATAL, "mutex_grab(%p(=%" PRIu32 ")) failed with %d\n",
35 &impl_, impl_.futex, ret);
36 }
37}
38
39void Mutex::Unlock() {
40 mutex_unlock(&impl_);
41}
42
43Mutex::State Mutex::TryLock() {
44 const int ret = mutex_trylock(&impl_);
45 switch (ret) {
46 case 0:
47 return State::kLocked;
Brian Silverman71c55c52014-08-19 14:31:59 -040048 case 1:
49 return State::kOwnerDied;
Brian Silvermandc1eb272014-08-19 14:25:59 -040050 case 4:
Daniel Petti88a15662015-04-12 17:42:22 -040051 return State::kLockFailed;
Brian Silvermandc1eb272014-08-19 14:25:59 -040052 default:
53 LOG(FATAL, "mutex_trylock(%p(=%" PRIu32 ")) failed with %d\n",
54 &impl_, impl_.futex, ret);
55 }
56}
57
Brian Silverman1dfe48b2014-09-06 16:13:02 -040058bool Mutex::OwnedBySelf() const {
59 return mutex_islocked(&impl_);
60}
61
Brian Silvermandc1eb272014-08-19 14:25:59 -040062} // namespace aos