blob: 57806990f6f02c9e97e2fe9b7f20d144e52623fa [file] [log] [blame]
Brian Silverman1ed5df52021-09-13 20:14:06 -07001#ifndef AOS_IPC_LIB_SHM_OBSERVERS_H_
2#define AOS_IPC_LIB_SHM_OBSERVERS_H_
3
4#include <type_traits>
5
6namespace aos {
7namespace linux_code {
8namespace ipc_lib {
9
10typedef void (*ShmAccessorObserver)(void *address, bool write);
11
12extern ShmAccessorObserver before_observer, after_observer;
13
14// Sets functions to run before and after SHM write operations which may
15// involved multiple instructions. This is important when doing robustness
16// testing because the memory has to be made writable for the whole operation,
17// otherwise it never succeeds.
18void SetShmAccessorObservers(ShmAccessorObserver before,
19 ShmAccessorObserver after);
20
21// RAII class which runs before_observer during construction and after_observer
22// during destruction.
23class RunShmObservers {
24 public:
25 template <class T>
26 RunShmObservers(T *address, bool write)
27 : address_(static_cast<void *>(
28 const_cast<typename ::std::remove_cv<T>::type *>(address))),
29 write_(write) {
30 if (__builtin_expect(before_observer != nullptr, false)) {
31 before_observer(address_, write_);
32 }
33 }
34 ~RunShmObservers() {
35 if (__builtin_expect(after_observer != nullptr, false)) {
36 after_observer(address_, write_);
37 }
38 }
39
40 RunShmObservers(const RunShmObservers &) = delete;
41 RunShmObservers &operator=(const RunShmObservers &) = delete;
42
43 private:
44 void *const address_;
45 const bool write_;
46};
47
48} // namespace ipc_lib
49} // namespace linux_code
50} // namespace aos
51
52#endif // AOS_IPC_LIB_SHM_OBSERVERS_H_