Skip to content

bench: add owner-death lock recovery benchmark and raw results - #250

Closed
Raja-89 wants to merge 2 commits into
Project-HAMi:mainfrom
Raja-89:evidence/owner-death-benchmark
Closed

bench: add owner-death lock recovery benchmark and raw results#250
Raja-89 wants to merge 2 commits into
Project-HAMi:mainfrom
Raja-89:evidence/owner-death-benchmark

Conversation

@Raja-89

@Raja-89 Raja-89 commented Aug 4, 2026

Copy link
Copy Markdown

Summary

Publishes the benchmark source and raw measurements used for the local /tmp
lock-strategy comparison discussed in #248.

The benchmark measures owner-death recovery latency for:

  • blocking F_SETLKW
  • nonblocking F_SETLK with exponential backoff and jitter modeled after the
    current recovery strategy

Included

  • owner_death_bench.c — benchmark source
  • owner-block.csv — 100 raw F_SETLKW samples
  • owner-poll.csv — 100 raw F_SETLK polling samples
  • README with build/run instructions and scope

Scope

These measurements were collected using a lock file under /tmp on a local
filesystem.

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 data
is 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

    • Added a benchmark comparing polling and blocking lock acquisition after the lock owner exits unexpectedly.
    • Reports lock recovery timing across selected acquisition strategies and handles cleanup and error conditions.
    • Supports repeatable benchmark runs with configurable modes and structured result output.
  • Documentation

    • Added setup and usage instructions, benchmark scope, filesystem considerations, sample counts, and raw CSV data details.

@hami-robot

hami-robot Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Raja-89
Once this PR has been reviewed and has the lgtm label, please assign archlitchi for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hami-robot

hami-robot Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Welcome @Raja-89! It looks like this is your first PR to Project-HAMi/HAMi-core 🎉

@hami-robot hami-robot Bot added the size/L label Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Raja-89, you've reached your PR review limit, so we couldn't start this review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8fb4f646-b056-478c-bd53-eba863655e15

📥 Commits

Reviewing files that changed from the base of the PR and between c90d41b and df588fd.

📒 Files selected for processing (2)
  • evidence/owner-death/README.md
  • evidence/owner-death/owner_death_bench.c.txt
📝 Walkthrough

Walkthrough

Adds 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.

Changes

Owner-death lock recovery

Layer / File(s) Summary
Lock acquisition and timing
evidence/owner-death/owner_death_bench.c
Adds monotonic timing, interruptible sleeps, randomized backoff, and polling or blocking fcntl lock acquisition.
Owner and waiter orchestration
evidence/owner-death/owner_death_bench.c
Creates the lock owner and waiter processes. The waiter selects the requested acquisition mode and reports its acquisition time.
Recovery flow and benchmark documentation
evidence/owner-death/owner_death_bench.c, evidence/owner-death/README.md
Terminates the owner, validates waiter results, prints recovery timing, cleans up resources, and documents usage and raw measurement files.

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
Loading

Suggested labels: enhancement

Suggested reviewers: chaunceyjiang, archlitchi

Poem

A rabbit watched the lock at night,
The owner vanished out of sight.
Polling hopped, blocking stayed,
Both measured paths the benchmark made.
Clean files closed before dawn.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the added owner-death lock recovery benchmark and its raw measurement results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Aug 4, 2026
Signed-off-by: Raja-89 <imraja729@gmail.com>
@Raja-89
Raja-89 force-pushed the evidence/owner-death-benchmark branch from 0098366 to c90d41b Compare August 4, 2026 12:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5496322 and 0098366.

⛔ Files ignored due to path filters (2)
  • evidence/owner-death/results/owner-block.csv is excluded by !**/*.csv
  • evidence/owner-death/results/owner-poll.csv is excluded by !**/*.csv
📒 Files selected for processing (2)
  • evidence/owner-death/README.md
  • evidence/owner-death/owner_death_bench.c

Comment on lines +16 to +17
static long long now_us(void)
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 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

Comment on lines +139 to +203
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 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.c

Repository: 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.c

Repository: 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}")
PY

Repository: 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.

Comment on lines +147 to +160
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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.c

Repository: 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 parent

Repository: 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 parent

Repository: 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:


🌐 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:


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.

Comment on lines +171 to +192
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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.

Comment on lines +30 to +35
The published raw data contains 100 samples for each mode.

## Raw data

- `results/owner-block.csv`
- `results/owner-poll.csv`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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"
done

Repository: 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
fi

Repository: 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>
@mesutoezdil

Copy link
Copy Markdown
Contributor

This is being closed because it does not comply with the contribution guidelines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants