redo the aos_sync API and add PI support
Previously, it didn't have different types for mutexes vs futexes and
the one common type was poorly named. It's hard to split that change out
from adding PI support, so they're both together. Adding PI support is
important because we have many places (ie the logging queue) where high-priority
and low-priority code interact heavily.
This change adds some small parts of robustness support, but they all
result in CHECK/assert failures if triggered.
Change-Id: I841ccee52568c32d453ed14f930430debbd8d78e
diff --git a/aos/linux_code/ipc_lib/mutex.cc b/aos/linux_code/ipc_lib/mutex.cc
new file mode 100644
index 0000000..9e270c9
--- /dev/null
+++ b/aos/linux_code/ipc_lib/mutex.cc
@@ -0,0 +1,54 @@
+#include "aos/common/mutex.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "aos/common/type_traits.h"
+#include "aos/common/logging/logging.h"
+
+namespace aos {
+
+Mutex::Mutex() : impl_() {
+ static_assert(shm_ok<Mutex>::value,
+ "Mutex is not safe for use in shared memory.");
+}
+
+Mutex::~Mutex() {
+ if (__builtin_expect(mutex_islocked(&impl_), 0)) {
+ LOG(FATAL, "destroying locked mutex %p (aka %p)\n",
+ this, &impl_);
+ }
+}
+
+// Lock and Unlock use the return values of mutex_lock/mutex_unlock
+// to determine whether the lock/unlock succeeded.
+
+bool Mutex::Lock() {
+ const int ret = mutex_grab(&impl_);
+ if (ret == 0) {
+ return false;
+ } else {
+ LOG(FATAL, "mutex_grab(%p(=%" PRIu32 ")) failed with %d\n",
+ &impl_, impl_.futex, ret);
+ }
+}
+
+void Mutex::Unlock() {
+ mutex_unlock(&impl_);
+}
+
+Mutex::State Mutex::TryLock() {
+ const int ret = mutex_trylock(&impl_);
+ switch (ret) {
+ case 0:
+ return State::kLocked;
+ case 4:
+ return State::kUnlocked;
+ default:
+ LOG(FATAL, "mutex_trylock(%p(=%" PRIu32 ")) failed with %d\n",
+ &impl_, impl_.futex, ret);
+ }
+}
+
+} // namespace aos