Robustness for posix spin locks










0















I'm writing a library that needs a fast ipc lock, around a small critical section. I want to ensure that crashes in unrelated code, during the critical section, will still release the ipc lock.



In this example, main creates a shared memory object and memory maps it. Initializes the memory as a pthread_spinlock_t with PTHREAD_PROCESS_SHARED, allowing multiple processes to use the same lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);


void proc2_main()
auto shm_obj = ...

this_thread::sleep_for(chrono::seconds(1));

cout << "waiting for spin lock...n";
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
cout << "got spin lockn";
pthread_spin_unlock((pthread_spinlock_t*)shm_obj.ptr);


int main()
auto shm_obj = ...
pthread_spin_init((pthread_spinlock_t*)shm_obj.ptr, PTHREAD_PROCESS_SHARED);
shm_obj.close();

if (::fork())
proc1_main();
else
proc2_main();




The sleeps ensure that process ordering is (more-or-less) guaranteed.




  • proc1 grabs the spin lock.


  • proc2 prints "waiting for spin lock...".


  • proc2 starts waiting on the spin lock.


  • proc1 releases the spin lock.


  • proc2 acquires the spin lock.


  • proc2 prints "got spin lock".


  • proc2 releases the spin lock.

This is all good and expected behavior for a lock.



I'm concerned what happens if a process crashes and doesn't release the lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
// pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);



With this modification, proc1 completes without releasing the spin lock. proc2 hangs forever.



If I was using a pthread_mutex_t, I could add the PTHREAD_MUTEX_ROBUST flag and continue on. I don't need to worry about consistency.



Is there any robustness for spin locks?










share|improve this question






















  • What kind of resource does the spin lock protect? What precisely do you want to happen if a process crashes while holding the spin lock? (For example, do you want the next thread to try to acquire the lock to just get it without being notified that whatever the lock protects may have been left in an inconsistent state?)

    – David Schwartz
    Nov 15 '18 at 0:20












  • @DavidSchwartz I just want the crashing program to release the lock. Far more detail: the lock protects a double-buffered struct in shared-memory. The critical section sets a few values in the writable buffer, then atomically swaps the buffers. The shared-memory is still always in a consistent state, even if the program crashes half way through, since the active buffer is always the result of the atomic swap.

    – user100046
    Nov 15 '18 at 0:34











  • That's a sufficiently unusual requirement that you'll probably need to make your own implementation.

    – David Schwartz
    Nov 15 '18 at 0:56











  • Is the assumption with PTHREAD_PROCESS_SHARED that none of the processes will crash? Is there really no way to recover?

    – user100046
    Nov 15 '18 at 1:03











  • The assumption is that if a process crashes while holding the lock, it may leave shared data in an inconsistent state and thus any recovery process will involve truly extraordinary measures such as terminating all processes that access the shared resource. You may have to use something like a file lock instead.

    – David Schwartz
    Nov 15 '18 at 1:33















0















I'm writing a library that needs a fast ipc lock, around a small critical section. I want to ensure that crashes in unrelated code, during the critical section, will still release the ipc lock.



In this example, main creates a shared memory object and memory maps it. Initializes the memory as a pthread_spinlock_t with PTHREAD_PROCESS_SHARED, allowing multiple processes to use the same lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);


void proc2_main()
auto shm_obj = ...

this_thread::sleep_for(chrono::seconds(1));

cout << "waiting for spin lock...n";
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
cout << "got spin lockn";
pthread_spin_unlock((pthread_spinlock_t*)shm_obj.ptr);


int main()
auto shm_obj = ...
pthread_spin_init((pthread_spinlock_t*)shm_obj.ptr, PTHREAD_PROCESS_SHARED);
shm_obj.close();

if (::fork())
proc1_main();
else
proc2_main();




The sleeps ensure that process ordering is (more-or-less) guaranteed.




  • proc1 grabs the spin lock.


  • proc2 prints "waiting for spin lock...".


  • proc2 starts waiting on the spin lock.


  • proc1 releases the spin lock.


  • proc2 acquires the spin lock.


  • proc2 prints "got spin lock".


  • proc2 releases the spin lock.

This is all good and expected behavior for a lock.



I'm concerned what happens if a process crashes and doesn't release the lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
// pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);



With this modification, proc1 completes without releasing the spin lock. proc2 hangs forever.



If I was using a pthread_mutex_t, I could add the PTHREAD_MUTEX_ROBUST flag and continue on. I don't need to worry about consistency.



Is there any robustness for spin locks?










share|improve this question






















  • What kind of resource does the spin lock protect? What precisely do you want to happen if a process crashes while holding the spin lock? (For example, do you want the next thread to try to acquire the lock to just get it without being notified that whatever the lock protects may have been left in an inconsistent state?)

    – David Schwartz
    Nov 15 '18 at 0:20












  • @DavidSchwartz I just want the crashing program to release the lock. Far more detail: the lock protects a double-buffered struct in shared-memory. The critical section sets a few values in the writable buffer, then atomically swaps the buffers. The shared-memory is still always in a consistent state, even if the program crashes half way through, since the active buffer is always the result of the atomic swap.

    – user100046
    Nov 15 '18 at 0:34











  • That's a sufficiently unusual requirement that you'll probably need to make your own implementation.

    – David Schwartz
    Nov 15 '18 at 0:56











  • Is the assumption with PTHREAD_PROCESS_SHARED that none of the processes will crash? Is there really no way to recover?

    – user100046
    Nov 15 '18 at 1:03











  • The assumption is that if a process crashes while holding the lock, it may leave shared data in an inconsistent state and thus any recovery process will involve truly extraordinary measures such as terminating all processes that access the shared resource. You may have to use something like a file lock instead.

    – David Schwartz
    Nov 15 '18 at 1:33













0












0








0


1






I'm writing a library that needs a fast ipc lock, around a small critical section. I want to ensure that crashes in unrelated code, during the critical section, will still release the ipc lock.



In this example, main creates a shared memory object and memory maps it. Initializes the memory as a pthread_spinlock_t with PTHREAD_PROCESS_SHARED, allowing multiple processes to use the same lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);


void proc2_main()
auto shm_obj = ...

this_thread::sleep_for(chrono::seconds(1));

cout << "waiting for spin lock...n";
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
cout << "got spin lockn";
pthread_spin_unlock((pthread_spinlock_t*)shm_obj.ptr);


int main()
auto shm_obj = ...
pthread_spin_init((pthread_spinlock_t*)shm_obj.ptr, PTHREAD_PROCESS_SHARED);
shm_obj.close();

if (::fork())
proc1_main();
else
proc2_main();




The sleeps ensure that process ordering is (more-or-less) guaranteed.




  • proc1 grabs the spin lock.


  • proc2 prints "waiting for spin lock...".


  • proc2 starts waiting on the spin lock.


  • proc1 releases the spin lock.


  • proc2 acquires the spin lock.


  • proc2 prints "got spin lock".


  • proc2 releases the spin lock.

This is all good and expected behavior for a lock.



I'm concerned what happens if a process crashes and doesn't release the lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
// pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);



With this modification, proc1 completes without releasing the spin lock. proc2 hangs forever.



If I was using a pthread_mutex_t, I could add the PTHREAD_MUTEX_ROBUST flag and continue on. I don't need to worry about consistency.



Is there any robustness for spin locks?










share|improve this question














I'm writing a library that needs a fast ipc lock, around a small critical section. I want to ensure that crashes in unrelated code, during the critical section, will still release the ipc lock.



In this example, main creates a shared memory object and memory maps it. Initializes the memory as a pthread_spinlock_t with PTHREAD_PROCESS_SHARED, allowing multiple processes to use the same lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);


void proc2_main()
auto shm_obj = ...

this_thread::sleep_for(chrono::seconds(1));

cout << "waiting for spin lock...n";
pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
cout << "got spin lockn";
pthread_spin_unlock((pthread_spinlock_t*)shm_obj.ptr);


int main()
auto shm_obj = ...
pthread_spin_init((pthread_spinlock_t*)shm_obj.ptr, PTHREAD_PROCESS_SHARED);
shm_obj.close();

if (::fork())
proc1_main();
else
proc2_main();




The sleeps ensure that process ordering is (more-or-less) guaranteed.




  • proc1 grabs the spin lock.


  • proc2 prints "waiting for spin lock...".


  • proc2 starts waiting on the spin lock.


  • proc1 releases the spin lock.


  • proc2 acquires the spin lock.


  • proc2 prints "got spin lock".


  • proc2 releases the spin lock.

This is all good and expected behavior for a lock.



I'm concerned what happens if a process crashes and doesn't release the lock.



void proc1_main() 
auto shm_obj = ...

pthread_spin_lock((pthread_spinlock_t*)shm_obj.ptr);
this_thread::sleep_for(chrono::seconds(2));
// pthread_spin_unlock((pthread_spinlock_t*)obj.ptr);



With this modification, proc1 completes without releasing the spin lock. proc2 hangs forever.



If I was using a pthread_mutex_t, I could add the PTHREAD_MUTEX_ROBUST flag and continue on. I don't need to worry about consistency.



Is there any robustness for spin locks?







pthreads posix spinlock






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 0:17









user100046user100046

5814




5814












  • What kind of resource does the spin lock protect? What precisely do you want to happen if a process crashes while holding the spin lock? (For example, do you want the next thread to try to acquire the lock to just get it without being notified that whatever the lock protects may have been left in an inconsistent state?)

    – David Schwartz
    Nov 15 '18 at 0:20












  • @DavidSchwartz I just want the crashing program to release the lock. Far more detail: the lock protects a double-buffered struct in shared-memory. The critical section sets a few values in the writable buffer, then atomically swaps the buffers. The shared-memory is still always in a consistent state, even if the program crashes half way through, since the active buffer is always the result of the atomic swap.

    – user100046
    Nov 15 '18 at 0:34











  • That's a sufficiently unusual requirement that you'll probably need to make your own implementation.

    – David Schwartz
    Nov 15 '18 at 0:56











  • Is the assumption with PTHREAD_PROCESS_SHARED that none of the processes will crash? Is there really no way to recover?

    – user100046
    Nov 15 '18 at 1:03











  • The assumption is that if a process crashes while holding the lock, it may leave shared data in an inconsistent state and thus any recovery process will involve truly extraordinary measures such as terminating all processes that access the shared resource. You may have to use something like a file lock instead.

    – David Schwartz
    Nov 15 '18 at 1:33

















  • What kind of resource does the spin lock protect? What precisely do you want to happen if a process crashes while holding the spin lock? (For example, do you want the next thread to try to acquire the lock to just get it without being notified that whatever the lock protects may have been left in an inconsistent state?)

    – David Schwartz
    Nov 15 '18 at 0:20












  • @DavidSchwartz I just want the crashing program to release the lock. Far more detail: the lock protects a double-buffered struct in shared-memory. The critical section sets a few values in the writable buffer, then atomically swaps the buffers. The shared-memory is still always in a consistent state, even if the program crashes half way through, since the active buffer is always the result of the atomic swap.

    – user100046
    Nov 15 '18 at 0:34











  • That's a sufficiently unusual requirement that you'll probably need to make your own implementation.

    – David Schwartz
    Nov 15 '18 at 0:56











  • Is the assumption with PTHREAD_PROCESS_SHARED that none of the processes will crash? Is there really no way to recover?

    – user100046
    Nov 15 '18 at 1:03











  • The assumption is that if a process crashes while holding the lock, it may leave shared data in an inconsistent state and thus any recovery process will involve truly extraordinary measures such as terminating all processes that access the shared resource. You may have to use something like a file lock instead.

    – David Schwartz
    Nov 15 '18 at 1:33
















What kind of resource does the spin lock protect? What precisely do you want to happen if a process crashes while holding the spin lock? (For example, do you want the next thread to try to acquire the lock to just get it without being notified that whatever the lock protects may have been left in an inconsistent state?)

– David Schwartz
Nov 15 '18 at 0:20






What kind of resource does the spin lock protect? What precisely do you want to happen if a process crashes while holding the spin lock? (For example, do you want the next thread to try to acquire the lock to just get it without being notified that whatever the lock protects may have been left in an inconsistent state?)

– David Schwartz
Nov 15 '18 at 0:20














@DavidSchwartz I just want the crashing program to release the lock. Far more detail: the lock protects a double-buffered struct in shared-memory. The critical section sets a few values in the writable buffer, then atomically swaps the buffers. The shared-memory is still always in a consistent state, even if the program crashes half way through, since the active buffer is always the result of the atomic swap.

– user100046
Nov 15 '18 at 0:34





@DavidSchwartz I just want the crashing program to release the lock. Far more detail: the lock protects a double-buffered struct in shared-memory. The critical section sets a few values in the writable buffer, then atomically swaps the buffers. The shared-memory is still always in a consistent state, even if the program crashes half way through, since the active buffer is always the result of the atomic swap.

– user100046
Nov 15 '18 at 0:34













That's a sufficiently unusual requirement that you'll probably need to make your own implementation.

– David Schwartz
Nov 15 '18 at 0:56





That's a sufficiently unusual requirement that you'll probably need to make your own implementation.

– David Schwartz
Nov 15 '18 at 0:56













Is the assumption with PTHREAD_PROCESS_SHARED that none of the processes will crash? Is there really no way to recover?

– user100046
Nov 15 '18 at 1:03





Is the assumption with PTHREAD_PROCESS_SHARED that none of the processes will crash? Is there really no way to recover?

– user100046
Nov 15 '18 at 1:03













The assumption is that if a process crashes while holding the lock, it may leave shared data in an inconsistent state and thus any recovery process will involve truly extraordinary measures such as terminating all processes that access the shared resource. You may have to use something like a file lock instead.

– David Schwartz
Nov 15 '18 at 1:33





The assumption is that if a process crashes while holding the lock, it may leave shared data in an inconsistent state and thus any recovery process will involve truly extraordinary measures such as terminating all processes that access the shared resource. You may have to use something like a file lock instead.

– David Schwartz
Nov 15 '18 at 1:33












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310705%2frobustness-for-posix-spin-locks%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310705%2frobustness-for-posix-spin-locks%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

What does pagestruct do in Eviews?

Dutch intervention in Lombok and Karangasem

Channel Islands