Use shared memory + spinlock & semaphore to perform IPC message passing in preload mode.#924
Use shared memory + spinlock & semaphore to perform IPC message passing in preload mode.#924rwails merged 17 commits intoshadow:devfrom
Conversation
plugin both implement the following IPC communication pattern:
plugin:
recv -> send -> recv -> send ...
shadow:
send -> recv -> send -> recv ...
This commit patches a case where shared memory communication would
sometimes cause the pattern:
shadow:
... send -> send -> recv ...
and vice-versa on the plugin.
This commit also implements a more sophisticated spin lock/semaphore in
the gate CPP module.
Codecov Report
@@ Coverage Diff @@
## dev #924 +/- ##
==========================================
- Coverage 55.74% 55.72% -0.03%
==========================================
Files 135 137 +2
Lines 20957 21015 +58
Branches 4833 4837 +4
==========================================
+ Hits 11683 11710 +27
- Misses 6106 6130 +24
- Partials 3168 3175 +7
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
src/main/host/thread_preload.c
Outdated
| SysCallHandler* sys; | ||
|
|
||
| int eventFD; | ||
| pid_t childPID; |
There was a problem hiding this comment.
The base Thread struct now has this
src/main/host/thread_preload.c
Outdated
| }; | ||
|
|
||
| shimevent_sendEvent(thread->eventFD, &ipc_complete_ev); | ||
| ShimEvent resp = {0}; |
There was a problem hiding this comment.
Nit - move to after next statement, just before first use?
src/shim/CMakeLists.txt
Outdated
| # -D_GNU_SOURCE enables some additional features in libc, such at RTLD_NEXT. | ||
| target_compile_options(${SHIM_HELPER_LIB} PRIVATE -D_GNU_SOURCE) | ||
| target_compile_options(${SHIM_HELPER_LIB} PRIVATE -D_GNU_SOURCE -fPIC) | ||
| target_link_libraries(${SHIM_HELPER_LIB} PRIVATE shadow-shmem) |
There was a problem hiding this comment.
I think this should be INTERFACE? I don't think PRIVATE makes sense for a static library target, since its dependencies won't actually be linked into the library; its dependencies need to be included by the binary target(s) that use the library.
From https://cmake.org/cmake/help/v3.0/command/target_link_libraries.html?highlight=target_link_libraries :
The PUBLIC, PRIVATE and INTERFACE keywords can be used to specify both the link dependencies and the link interface in one command. Libraries and targets following PUBLIC are linked to, and are made part of the link interface. Libraries and targets following PRIVATE are linked to, but are not made part of the link interface. Libraries following INTERFACE are appended to the link interface and are not used for linking .
There was a problem hiding this comment.
Changed to interface.
src/shim/gate.cc
Outdated
| #define SHD_GATE_SPIN_MAX 8096 | ||
|
|
||
| void gate_init(Gate *gate) { | ||
| std::memset(gate, 0, sizeof(Gate)); |
There was a problem hiding this comment.
IIRC memset'ing an object to zero is a bit of a gray area for type safety in the standard. It's probably fine in practice, but better to either use struct initialization to default-init the struct in a type-aware way (*gate = {0}), and/or explicitly init all members (gate->x is currently not initialized other than in this memset).
There was a problem hiding this comment.
Fixed. n.b. C++ doesn't support the lovely = {0} syntax to zero all struct members.
src/shim/gate.h
Outdated
| pthread_spinlock_t lock; | ||
| }; | ||
|
|
||
| void gate_init(Gate *gate); |
There was a problem hiding this comment.
I'm struggling a little bit with the "gate" metaphor. Could perhaps use a brief explanation (and/or a reference if it's a standard term, though I didn't have much luck searching)
There was a problem hiding this comment.
Renamed to BinarySpinningSem
| } | ||
|
|
||
| #ifndef NDEBUG | ||
| static void _print(void* pool, size_t pool_nbytes, void* meta) { |
There was a problem hiding this comment.
Maybe keep around in case you want it again for debugging? You could just #if 0 it out to avoid dead code warnings.
There was a problem hiding this comment.
I think let's leave it out. The block is pretty old and probably only makes sense to me. I can dig it out of the history if needed.
src/shim/ipc.cc
Outdated
| extern "C" { | ||
|
|
||
| void ipcData_init(IPCData *ipc_data) { | ||
| memset(ipc_data, 0, sizeof(IPCData)); |
There was a problem hiding this comment.
As before, memset is a bit fragile here. Now I remember that this is especially the case for a C++ object, since a memset won't run the constructors of any member objects, if applicable.
As far as I can tell struct init does technically work here, but actually is also fragile due to c++ destuctors: if IPCData or any of its members have destructors, they'd run on the garbage data at ipc_data before calling IPCData's constructor (you haven't defined one, but IIRC there's implicitly one that default-initializes all members).
I think the idiomatic, safe way to do this is to replace IPCData::init with a constructor IPDCata::IPCData, and here use a placement new.
There was a problem hiding this comment.
Alternatively, we could add a static assertion that IPCData (and therefore its members) doesn't have any nontrivial constructor or destructors, in which case the struct-init, or even the memset, should be safe: https://godbolt.org/z/c6nsTa
void ipcData_init(IPCData *ipc_data) {
static_assert(std::is_trivial<IPCData>());
static_assert(std::is_trivially_destructible<IPCData>());
*ipc_data = {};
}
There was a problem hiding this comment.
Good catch! I think memsetting a class has bitten me before. I had heard of placement new, but had forgotten its use since. Fixed!
sporksmith
left a comment
There was a problem hiding this comment.
Looks good! The coverage test is currently broken, so you can ignore that failure. @stevenengler is about to disable it.
You should be able to fix the bindings-lint check by running cd build; make bindings. (You may need to install bindgen and cbindgen first if you haven't already)
Actually the binding failure is spurious too; will be fixed by #940 |
|
All of the CI issues should be resolved now. |
No description provided.