Replace pthread's rwlock with a FIFO-queueing read-write lock #14839
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR aims to introduce a FIFO-queueing read-write lock shared library, and replace the pthread's
rwlock
objects with this new structure.Rationale
Some modules in Wazuh, such as Remoted and Logcollector, are made up of several threads that access memory in different ways:
In order to prevent data access serialization in reading mode, those modules use read-write locks from the POSIX threads library. This implementation gives preference to readers, which may lead to writer starvation when those modules are highly loaded as there always be many readers working (see #2761).
We solved that problem using the following call, which sets the preference for writers:
That function is non-portable (as the
_np
suffix indicates), and is available in the GNU C Library. However, this makes it impossible to compile with the musl library, thus porting Wazuh to platforms like Alpine Linux (avoiding writer starvation).Proof of concept
Code
main.c
Test (starvation)
There is no output: the writer is starved.
Test (prevent starvation)
The program prints precisely one line per second, indicating that the writer is working as expected.
Proposed fix
Enclose calls to lock the read-writer locks either in read or write mode, pretending this behavior:
This way, we implement a structure
rwlock_t
with its respective functions and replace the usage ofpthread_rwlock_t
with this new library in:We have decided to omit to refactor the structure
OSHash
due to its complexity and scope (Analysisd).Proof of concept (1)
Code
rwlock.h
rwlock.c
main.c
Test
gcc -O2 -pthread -o rwtest_1 *.c ./rwtest_1
Proof of concept (2)
This is a variant with a custom implementation of the read-write lock, using a counter and a condition variable.
rwlock.h
rwlock.c
main.c
Test
gcc -O2 -pthread -o rwtest_2 *.c ./rwtest_2
Footprint test
We ran the three implementations, having the following CPU usage:
rwtest_cur
(current)rwtest_1
(proposal 1)rwtest_2
(proposal 2)Having that both fixes meet the functional expectations, and the first one adds an imperceptible overhead, we decided to apply the first fix.
Tests