bench: add owner-death lock recovery benchmark and raw results - #250
bench: add owner-death lock recovery benchmark and raw results#250Raja-89 wants to merge 2 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Raja-89 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Welcome @Raja-89! It looks like this is your first PR to Project-HAMi/HAMi-core 🎉 |
|
Warning Review limit reached
Next review available in: 45 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a C benchmark that compares polling and blocking record-lock recovery after forced owner termination. It measures recovery time, validates child results, cleans up resources, and documents build commands, filesystem scope, and raw sample data. ChangesOwner-death lock recovery
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Parent
participant Owner
participant Waiter
Parent->>Owner: Create and acquire record lock
Owner-->>Parent: Signal readiness
Parent->>Waiter: Start selected acquisition mode
Parent->>Owner: Kill lock owner
Waiter->>Waiter: Poll or block for lock recovery
Waiter-->>Parent: Report recovery timestamp
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Raja-89 <imraja729@gmail.com>
0098366 to
c90d41b
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@evidence/owner-death/owner_death_bench.c`:
- Around line 16-17: Update the timing declarations and output in
owner_death_bench.c: use the required brace placement, replace long-based timing
values with int64_t, and use the matching PRId64 format for printf calls. Remove
the unused before variable or use it where required, while preserving the
benchmark behavior.
- Around line 171-192: Replace the fixed usleep(100000) delay in the owner-death
benchmark with strategy-specific synchronization that signals when the waiter
has entered F_SETLKW or the polling loop. Have the parent wait for that
readiness signal before killing the owner, while preserving the existing
acquisition timing and result-pipe flow.
- Around line 139-203: Check the return values of the initial ready pipe and
owner fork before using their descriptors or PID, reporting the failure and
exiting safely. Apply the same validation to the result pipe and waiter fork,
ensuring cleanup paths never use invalid descriptors or call kill with a failed
PID; exit with an error on any failure.
- Around line 147-160: Validate the readiness handshake in the parent after read
and before starting the waiter: require read to return exactly one byte and
require that byte to be "R". If validation fails, reap owner and exit with an
error; only proceed to waiter startup when the owner has confirmed it holds the
record lock.
In `@evidence/owner-death/README.md`:
- Around line 30-35: Add the missing results/owner-block.csv and
results/owner-poll.csv files containing the documented 100-sample raw benchmark
data for each mode, so the existing Raw data references in README.md resolve
correctly.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 57449324-2814-4841-a809-2d7bb80ed56f
⛔ Files ignored due to path filters (2)
evidence/owner-death/results/owner-block.csvis excluded by!**/*.csvevidence/owner-death/results/owner-poll.csvis excluded by!**/*.csv
📒 Files selected for processing (2)
evidence/owner-death/README.mdevidence/owner-death/owner_death_bench.c
| static long long now_us(void) | ||
| { |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the current style and compiler warnings.
The supplied cpplint jobs fail on the brace placement and long declarations. Use the required brace style. Use int64_t for timing values and a matching printf format such as PRId64. Also remove or use before at Line 171 because the documented -Wall -Wextra command reports it as unused.
Also applies to: 20-20, 24-24, 27-27, 35-35, 48-48, 61-61, 95-95, 113-113, 125-125, 171-171, 177-177, 194-194, 199-199
🧰 Tools
🪛 GitHub Actions: style / 0_cpplint.txt
[error] 16-16: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
[error] 17-17: cpplint: { should almost always be at the end of the previous line (whitespace/braces).
🪛 GitHub Actions: style / cpplint
[error] 16-16: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
[error] 17-17: cpplint: { should almost always be at the end of the previous line. (whitespace/braces)
🪛 GitHub Check: cpplint
[failure] 17-17:
[cpplint] reported by reviewdog 🐶
{ should almost always be at the end of the previous line [whitespace/braces] [4]
Raw Output:
evidence/owner-death/owner_death_bench.c:17: { should almost always be at the end of the previous line [whitespace/braces] [4]
[failure] 16-16:
[cpplint] reported by reviewdog 🐶
Use int16_t/int64_t/etc, rather than the C type long [runtime/int] [4]
Raw Output:
evidence/owner-death/owner_death_bench.c:16: Use int16_t/int64_t/etc, rather than the C type long [runtime/int] [4]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@evidence/owner-death/owner_death_bench.c` around lines 16 - 17, Update the
timing declarations and output in owner_death_bench.c: use the required brace
placement, replace long-based timing values with int64_t, and use the matching
PRId64 format for printf calls. Remove the unused before variable or use it
where required, while preserving the benchmark behavior.
Sources: Linters/SAST tools, Pipeline failures
| int ready[2]; | ||
| pipe(ready); | ||
|
|
||
| pid_t owner = fork(); | ||
|
|
||
| if (owner == 0) { | ||
| close(ready[0]); | ||
|
|
||
| if (lock_now(fd) != 0) | ||
| _exit(10); | ||
|
|
||
| write(ready[1], "R", 1); | ||
|
|
||
| /* Must die while owning the record lock */ | ||
| for (;;) | ||
| pause(); | ||
| } | ||
|
|
||
| close(ready[1]); | ||
|
|
||
| char c; | ||
| read(ready[0], &c, 1); | ||
| close(ready[0]); | ||
|
|
||
| int result[2]; | ||
| pipe(result); | ||
|
|
||
| pid_t waiter = fork(); | ||
|
|
||
| if (waiter == 0) { | ||
| close(result[0]); | ||
|
|
||
| long long before = now_us(); | ||
|
|
||
| int rc = !strcmp(argv[1], "poll") | ||
| ? acquire_poll(fd) | ||
| : acquire_block(fd); | ||
|
|
||
| long long acquired = now_us(); | ||
|
|
||
| if (rc != 0) | ||
| _exit(11); | ||
|
|
||
| write(result[1], &acquired, sizeof(acquired)); | ||
| close(result[1]); | ||
| _exit(0); | ||
| } | ||
|
|
||
| close(result[1]); | ||
|
|
||
| /* | ||
| * Give waiter 100 ms to reach F_SETLKW or the polling loop. | ||
| */ | ||
| usleep(100000); | ||
|
|
||
| long long killed = now_us(); | ||
|
|
||
| kill(owner, SIGKILL); | ||
| waitpid(owner, NULL, 0); | ||
|
|
||
| long long acquired; | ||
|
|
||
| if (read(result[0], &acquired, sizeof(acquired)) != sizeof(acquired)) { | ||
| fprintf(stderr, "failed to receive waiter result\n"); | ||
| kill(waiter, SIGKILL); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 5 '\b(pipe|fork|kill|waitpid)\s*\(' evidence/owner-death/owner_death_bench.cRepository: Project-HAMi/HAMi-core
Length of output: 1282
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '120,215p' evidence/owner-death/owner_death_bench.cRepository: Project-HAMi/HAMi-core
Length of output: 2014
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path("evidence/owner-death/owner_death_bench.c")
text = p.read_text().splitlines()
def block_start(line):
return line < len(text) and text[line].strip().startswith("if (") and "==" in text[line]
def closes_in_block(start, end, fd):
for i in range(start, end):
s = text[i].strip()
if f"close({fd});" in s or f"close({fd}[1]);" in s or f"close({fd}[0]);" in s:
return True
return False
forks = []
for i, line in enumerate(text, 1):
if "pid_t owner = fork();" in line:
forks.append(("owner", i))
if "pid_t waiter = fork();" in line:
forks.append(("waiter", i))
for name, line in forks:
idx = line - 1
close = closes_in_block(idx + 1, idx + 1 + 30, name if name == "owner" else "result")
uses_1 = "kill(-1," in "".join(text[idx:idx+80]), "kill(owner," in "".join(text[idx:idx+80])
print(f"{name} fork at main line {line}: immediate descriptor closed={close}")
PYRepository: Project-HAMi/HAMi-core
Length of output: 286
Handle pipe() and fork() failures before using descriptors or PIDs.
If pipe(ready) fails, the parent still closes and reads from ready as if it were valid. If fork() returns -1, owner is treated as a real child and kill(owner, SIGKILL) becomes kill(-1, SIGKILL), which signals the process group instead of terminating a single task. Apply the same checks for the second pipe(result) and waiter fork. Exit with an error instead of using invalid descriptors or PIDs.
🧰 Tools
🪛 GitHub Actions: style / 0_cpplint.txt
[error] 171-171: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
[error] 177-177: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
[error] 194-194: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
[error] 199-199: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
🪛 GitHub Actions: style / cpplint
[error] 171-171: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
[error] 177-177: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
[error] 194-194: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
[error] 199-199: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@evidence/owner-death/owner_death_bench.c` around lines 139 - 203, Check the
return values of the initial ready pipe and owner fork before using their
descriptors or PID, reporting the failure and exiting safely. Apply the same
validation to the result pipe and waiter fork, ensuring cleanup paths never use
invalid descriptors or call kill with a failed PID; exit with an error on any
failure.
| if (lock_now(fd) != 0) | ||
| _exit(10); | ||
|
|
||
| write(ready[1], "R", 1); | ||
|
|
||
| /* Must die while owning the record lock */ | ||
| for (;;) | ||
| pause(); | ||
| } | ||
|
|
||
| close(ready[1]); | ||
|
|
||
| char c; | ||
| read(ready[0], &c, 1); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file and relevant sections =="
wc -l evidence/owner-death/owner_death_bench.c
cat -n evidence/owner-death/owner_death_bench.c | sed -n '1,240p'
echo "== lock_now and fork/writer usages in file =="
rg -n "lock_now|fork|write\(ready|read\(ready|pause\(" evidence/owner-death/owner_death_bench.cRepository: Project-HAMi/HAMi-core
Length of output: 6250
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== behavioral probe for pipe EOF when writer exits before writing =="
cat >/tmp/ready_eof_probe.c <<'EOF'
`#include` <unistd.h>
`#include` <stdio.h>
`#include` <stdlib.h>
`#include` <fcntl.h>
`#include` <sys/wait.h>
static int lock_now_fails(int fd_used)
{
return fd_use != 0 && (fd_used - 1); /* compile-time irrelevant, keep argc signature in same file */
}
int main(int argc, char **argv)
{
int ready[2];
pipe(ready);
int parent_path = argc > 1 && (argv[1][0] == 'p');
pid_t child = fork();
if (!child) {
close(ready[0]);
if (!parent_path) {
/* Simulate lock_now(fd) failure: the owner exits before writing "R" */
_exit(10);
}
if (write(ready[1], "R", 1) != 1)
_exit(20);
for (;;) pause();
}
close(ready[1]);
char c;
ssize_t n = read(ready[0], &c, 1);
close(ready[0]);
waitpid(child, NULL, 0);
int waiter_rc = 32;
pid_t waiter = fork();
if (!waiter) {
/* Simulate waiter waiting, then exiting because no owner held the lock */
_exit(waiter_rc);
}
waitpid(waiter, NULL, &waiter_rc);
printf("read=%zd byte=%02x waiter_rc=%d\n", n, (unsigned char)'\000', waiter_rc);
return 0;
}
EOF
gcc -Wall -Werror -O2 /tmp/ready_eof_probe.c -o /tmp/ready_eof_probe
/tmp/ready_eof_probe child
/tmp/ready_eof_probe parentRepository: Project-HAMi/HAMi-core
Length of output: 271
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== behavioral probe for pipe EOF when writer exits before writing =="
cat >/tmp/ready_eof_probe.c <<'EOF'
`#include` <unistd.h>
`#include` <stdio.h>
`#include` <stdlib.h>
`#include` <fcntl.h>
`#include` <sys/wait.h>
int main(int argc, char **argv)
{
int ready[2];
pipe(ready);
int parent_path = argc > 1 && (argv[1][0] == 'p');
pid_t child = fork();
if (!child) {
close(ready[0]);
if (!parent_path) {
/* Simulate lock_now(fd) failure: the owner exits before writing "R" */
_exit(10);
}
if (write(ready[1], "R", 1) != 1)
_exit(20);
for (;;) pause();
}
close(ready[1]);
char c;
ssize_t n = read(ready[0], &c, 1);
close(ready[0]);
waitpid(child, NULL, 0);
int waiter_rc = 32;
pid_t waiter = fork();
if (!waiter) {
/* Simulate waiter waiting, then exiting because no owner held the lock */
_exit(waiter_rc);
}
waitpid(waiter, NULL, &waiter_rc);
printf("read=%zd byte=%02x waiter_rc=%d\n", n, (unsigned char)'\000', waiter_rc);
return 0;
}
EOF
gcc -Wall -Werror -O2 /tmp/ready_eof_probe.c -o /tmp/ready_eof_probe
echo "child path, simulating lock_now failure:"
/tmp/ready_eof_probe child
echo "parent path, simulating lock acquisition:"
/tmp/ready_eof_probe parentRepository: Project-HAMi/HAMi-core
Length of output: 271
🌐 Web query:
POSIX pipe read EOF when all file descriptors are closed write end closed documentation
💡 Result:
Under the POSIX standard, when all file descriptors associated with the write end of a pipe are closed, any subsequent attempts to read from the read end of that pipe will encounter an end-of-file (EOF) condition [1][2][3]. In this state, the read system call returns 0 to indicate that no further data will be available from the pipe [4][5]. This behavior is fundamental to how pipes signal the completion of data transmission [1][3]. To ensure that EOF is correctly delivered, all processes must close any unused file descriptors (specifically, the write end in a reader process and the read end in a writer process) [6][7][8]. If even a single file descriptor referring to the write end remains open in any process, a read call on the pipe will block (or return EAGAIN if O_NONBLOCK is set) instead of returning EOF, because the system assumes that more data could still potentially be written [1][5]. Top Results: [1][6][5]
Citations:
- 1: https://man7.org/linux/man-pages/man7/pipe.7.html
- 2: https://man.archlinux.org/man/pipe.7.en
- 3: https://manpages.debian.org/7/pipe.en.html
- 4: https://stackoverflow.com/questions/48717635/reading-from-a-pipe-even-after-the-write-end-is-closed
- 5: https://pubs.opengroup.org/onlinepubs/9799919799/functions/read.html
- 6: https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/functions/pipe.html
- 7: https://www.man7.org/linux/man-pages/man2/pipe.2.html
- 8: https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pipe2.html
🌐 Web query:
POSIX pipe read EOF condition all write descriptors closed read end blocks
💡 Result:
Under POSIX standards, the behavior of a read operation on a pipe when all write descriptors are closed is as follows: When a process attempts to read from a pipe, if all file descriptors that refer to the write end of the pipe have been closed, the read function will return 0, which serves as the standard indication of end-of-file (EOF) [1][2][3]. This behavior occurs regardless of whether the pipe is empty or contains buffered data. If data remains in the pipe after all write descriptors are closed, the read call will first return all available data in the pipe; once the pipe is drained, subsequent read calls will return 0 [1][4]. In contrast, if at least one process still has the pipe open for writing, the behavior depends on the state of the O_NONBLOCK flag [2][5]: - If O_NONBLOCK is clear (default), the read call will block the calling thread until either some data is written to the pipe or all write descriptors are closed [2][6][7]. - If O_NONBLOCK is set, the read call will not block and will instead return -1 with errno set to [EAGAIN] (or [EWOULDBLOCK]), provided no data is currently available in the pipe [2][5][7].
Citations:
- 1: https://man7.org/linux/man-pages/man7/pipe.7.html
- 2: https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/read.html
- 3: https://linux.die.net/man/7/pipe
- 4: https://stackoverflow.com/questions/48717635/reading-from-a-pipe-even-after-the-write-end-is-closed
- 5: https://manned.org/man/read.3posix
- 6: https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/functions/read.html
- 7: https://pubs.opengroup.org/onlinepubs/9799919799/functions/read.html
Require "R" before starting the waiter.
If lock_now(fd) fails, the owner exits and closes the pipe, so the parent read returns EOF. The current code then starts the waiter with no locked owner; the waiter can miss contention and report an inflated recovery time, or the parent can continue to the kill/wait sequence expecting owned-lock behavior.
Count the byte: if read(ready[0], &c, 1) is not exactly 1 or c is not "R", reap owner and exit with an error.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@evidence/owner-death/owner_death_bench.c` around lines 147 - 160, Validate
the readiness handshake in the parent after read and before starting the waiter:
require read to return exactly one byte and require that byte to be "R". If
validation fails, reap owner and exit with an error; only proceed to waiter
startup when the owner has confirmed it holds the record lock.
| long long before = now_us(); | ||
|
|
||
| int rc = !strcmp(argv[1], "poll") | ||
| ? acquire_poll(fd) | ||
| : acquire_block(fd); | ||
|
|
||
| long long acquired = now_us(); | ||
|
|
||
| if (rc != 0) | ||
| _exit(11); | ||
|
|
||
| write(result[1], &acquired, sizeof(acquired)); | ||
| close(result[1]); | ||
| _exit(0); | ||
| } | ||
|
|
||
| close(result[1]); | ||
|
|
||
| /* | ||
| * Give waiter 100 ms to reach F_SETLKW or the polling loop. | ||
| */ | ||
| usleep(100000); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
git ls-files | rg '(^|/)evidence/owner-death/owner_death_bench\.c$|owner_death_bench\.c$' || true
echo "== file outline =="
ast-grep outline evidence/owner-death/owner_death_bench.c --view expanded || true
echo "== relevant source lines =="
sed -n '1,240p' evidence/owner-death/owner_death_bench.c
echo "== related files =="
git ls-files evidence/owner-death | sed -n '1,200p'Repository: Project-HAMi/HAMi-core
Length of output: 5032
Use synchronization instead of usleep(100000) before killing the owner.
The waiter can be descheduled for more than 100 ms, so kill(owner, SIGKILL) can run before the waiter enters F_SETLKW or its polling loop. The measured recovery_us then includes arbitrary scheduling delay, not lock recovery latency. Add strategy-specific synchronization so the owner is killed only after the waiter has reached its lock-acquisition path.
🧰 Tools
🪛 GitHub Actions: style / 0_cpplint.txt
[error] 171-171: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
[error] 177-177: cpplint: Use int16_t/int64_t/etc. rather than the C type long (runtime/int).
🪛 GitHub Actions: style / cpplint
[error] 171-171: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
[error] 177-177: cpplint: Use int16_t/int64_t/etc. rather than the C type long. (runtime/int)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@evidence/owner-death/owner_death_bench.c` around lines 171 - 192, Replace the
fixed usleep(100000) delay in the owner-death benchmark with strategy-specific
synchronization that signals when the waiter has entered F_SETLKW or the polling
loop. Have the parent wait for that readiness signal before killing the owner,
while preserving the existing acquisition timing and result-pipe flow.
| The published raw data contains 100 samples for each mode. | ||
|
|
||
| ## Raw data | ||
|
|
||
| - `results/owner-block.csv` | ||
| - `results/owner-poll.csv` |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for file in results/owner-block.csv results/owner-poll.csv; do
test -f "$file"
awk -F, '
NR == 1 { if ($0 != "mode,recovery_us,recovery_ms") exit 1; next }
NF != 3 { exit 1 }
END { exit (NR == 101 ? 0 : 1) }
' "$file"
doneRepository: Project-HAMi/HAMi-core
Length of output: 160
🏁 Script executed:
#!/bin/bash
set -u
for file in results/owner-block.csv results/owner-poll.csv; do
if test -f "$file"; then
echo "FOUND $file ($(wc -l < "$file") lines)"
head -n 4 "$file"
else
echo "MISSING $file"
fi
done
echo "README excerpt:"
if test -f evidence/owner-death/README.md; then
sed -n '25,38p' evidence/owner-death/README.md
fiRepository: Project-HAMi/HAMi-core
Length of output: 477
Publish the raw-data CSVs referenced by the README.
results/owner-block.csv and results/owner-poll.csv are missing, so readers cannot access the documented 100-sample benchmark data. Add the CSVs before documenting them under Raw data.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@evidence/owner-death/README.md` around lines 30 - 35, Add the missing
results/owner-block.csv and results/owner-poll.csv files containing the
documented 100-sample raw benchmark data for each mode, so the existing Raw data
references in README.md resolve correctly.
Signed-off-by: Raja-89 <imraja729@gmail.com>
|
This is being closed because it does not comply with the contribution guidelines. |
Summary
Publishes the benchmark source and raw measurements used for the local
/tmplock-strategy comparison discussed in #248.
The benchmark measures owner-death recovery latency for:
F_SETLKWF_SETLKwith exponential backoff and jitter modeled after thecurrent recovery strategy
Included
owner_death_bench.c— benchmark sourceowner-block.csv— 100 rawF_SETLKWsamplesowner-poll.csv— 100 rawF_SETLKpolling samplesScope
These measurements were collected using a lock file under
/tmpon a localfilesystem.
They are intended as a local-filesystem lock-strategy comparison and should
not be generalized to NFS behavior.
As discussed in #248, the NFSv4.2 results show different wake/recovery
characteristics for blocking
F_SETLKW. The purpose of publishing this datais to make the local results reproducible and allow the same benchmark to be
run across both local and NFS paths.
No production locking behavior is changed by this commit.
Summary by CodeRabbit
New Features
Documentation