Passing objects atomically across threads without locks or data races for audio synchronizationTwo threads...
School performs periodic password audits. Is my password compromised?
“I had a flat in the centre of town, but I didn’t like living there, so …”
What is a term for a function that when called repeatedly, has the same effect as calling once?
How do I deal with being envious of my own players?
Specific Chinese carabiner QA?
Deal the cards to the players
Can I solder 12/2 Romex to extend wire 5 ft?
Reason why dimensional travelling would be restricted
When do _WA_Sys_ statistics Get Updated?
Caulking a corner instead of taping with joint compound?
The need of reserving one's ability in job interviews
Split a number into equal parts given the number of parts
Being asked to review a paper in conference one has submitted to
Must 40/100G uplink ports on a 10G switch be connected to another switch?
Can a space-faring robot still function over a billion years?
Rationale to prefer local variables over instance variables?
PTIJ: Aharon, King of Egypt
When to use mean vs median
How does insurance birth control work?
Meaning of word ягоза
Should I use HTTPS on a domain that will only be used for redirection?
If nine coins are tossed, what is the probability that the number of heads is even?
Quitting employee has privileged access to critical information
Why doesn't "adolescent" take any articles in "listen to adolescent agonising"?
Passing objects atomically across threads without locks or data races for audio synchronization
Two threads working on shared dataPolymorphic STL foreach without passing the container typePass pointer data across multiple functionsPassing objects to functions safely and efficientlyQueue implementation without using built-in data structuresShare data and mutexes across threadsPassing C++ objects by reference for participants in a simulated battleSharing data between two threads C++Passing Objects of Classes to other ClassCRC without knowing the data type or size
$begingroup$
I am learning about one of the hardest parts of Audio development: the synchronization between the audio thread and the GUI thread. Per the discussion here https://forum.juce.com/t/timur-doumler-talks-on-c-audio-sharing-data-across-threads/26311 and here: https://stackoverflow.com/questions/15460829/lock-free-swap-of-two-unique-ptrt
I'm wondering if the following class solves the problem or comes close to solving it.
template<typename T>
struct SmartAtomicPtr
{
SmartAtomicPtr( T* newT )
{
update( newT );
}
~SmartAtomicPtr()
{
update(nullptr);
}
void update( T* newT, std::memory_order ord = memory_order_seq_cst )
{
keepAlive.reset( atomicTptr.exchange( newT, ord ) );
}
std::shared_ptr<T> getShared(std::memory_order ord = memory_order_seq_cst)
{
return std::make_shared<T>( atomicTptr.load(ord) );
}
T* getRaw(std::memory_order ord = memory_order_seq_cst)
{
return atomicTptr.load(ord);
}
private:
std::atomic<T*> atomicTptr{nullptr};
std::shared_ptr<T> keepAlive;
};
I know that whatever value ends up in the shared_ptr won't be deleted until the SmartAtomicPtr goes out of scope, which is fine.
the ultimate goal would be a lock-free, wait-free solution.
an example of where this might get used is the following interleaving of the audio and message thread. The goal is to keep the returned object from dangling
/*
AudioProcessor owns a SmartAtomicPtr<T> ptr that the message
thread has public access to.
*/
/* audio thread */ auto* t = ptr.getRaw();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is a dangling pointer now
with getShared(), I believe that t no longer dangles:
/* audio thread */ auto t = ptr.getShared();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is one of 2 shared_ptrs
//holding the previous atomic value of ptr
I ran into some double-deletes, but I believe I have solved them, and also prevented the shared_ptr member from being stomped on in the event you call getShared() and update() at the same time, and also kept it leak-free.
any thoughts?
c++ pointers audio lock-free atomic
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
I am learning about one of the hardest parts of Audio development: the synchronization between the audio thread and the GUI thread. Per the discussion here https://forum.juce.com/t/timur-doumler-talks-on-c-audio-sharing-data-across-threads/26311 and here: https://stackoverflow.com/questions/15460829/lock-free-swap-of-two-unique-ptrt
I'm wondering if the following class solves the problem or comes close to solving it.
template<typename T>
struct SmartAtomicPtr
{
SmartAtomicPtr( T* newT )
{
update( newT );
}
~SmartAtomicPtr()
{
update(nullptr);
}
void update( T* newT, std::memory_order ord = memory_order_seq_cst )
{
keepAlive.reset( atomicTptr.exchange( newT, ord ) );
}
std::shared_ptr<T> getShared(std::memory_order ord = memory_order_seq_cst)
{
return std::make_shared<T>( atomicTptr.load(ord) );
}
T* getRaw(std::memory_order ord = memory_order_seq_cst)
{
return atomicTptr.load(ord);
}
private:
std::atomic<T*> atomicTptr{nullptr};
std::shared_ptr<T> keepAlive;
};
I know that whatever value ends up in the shared_ptr won't be deleted until the SmartAtomicPtr goes out of scope, which is fine.
the ultimate goal would be a lock-free, wait-free solution.
an example of where this might get used is the following interleaving of the audio and message thread. The goal is to keep the returned object from dangling
/*
AudioProcessor owns a SmartAtomicPtr<T> ptr that the message
thread has public access to.
*/
/* audio thread */ auto* t = ptr.getRaw();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is a dangling pointer now
with getShared(), I believe that t no longer dangles:
/* audio thread */ auto t = ptr.getShared();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is one of 2 shared_ptrs
//holding the previous atomic value of ptr
I ran into some double-deletes, but I believe I have solved them, and also prevented the shared_ptr member from being stomped on in the event you call getShared() and update() at the same time, and also kept it leak-free.
any thoughts?
c++ pointers audio lock-free atomic
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
$begingroup$
From C++20, there'sstd::atomic<shared_ptr<T>>partial specialization. You'll want to understand how it works if you're implementing your own.
$endgroup$
– Toby Speight
9 hours ago
add a comment |
$begingroup$
I am learning about one of the hardest parts of Audio development: the synchronization between the audio thread and the GUI thread. Per the discussion here https://forum.juce.com/t/timur-doumler-talks-on-c-audio-sharing-data-across-threads/26311 and here: https://stackoverflow.com/questions/15460829/lock-free-swap-of-two-unique-ptrt
I'm wondering if the following class solves the problem or comes close to solving it.
template<typename T>
struct SmartAtomicPtr
{
SmartAtomicPtr( T* newT )
{
update( newT );
}
~SmartAtomicPtr()
{
update(nullptr);
}
void update( T* newT, std::memory_order ord = memory_order_seq_cst )
{
keepAlive.reset( atomicTptr.exchange( newT, ord ) );
}
std::shared_ptr<T> getShared(std::memory_order ord = memory_order_seq_cst)
{
return std::make_shared<T>( atomicTptr.load(ord) );
}
T* getRaw(std::memory_order ord = memory_order_seq_cst)
{
return atomicTptr.load(ord);
}
private:
std::atomic<T*> atomicTptr{nullptr};
std::shared_ptr<T> keepAlive;
};
I know that whatever value ends up in the shared_ptr won't be deleted until the SmartAtomicPtr goes out of scope, which is fine.
the ultimate goal would be a lock-free, wait-free solution.
an example of where this might get used is the following interleaving of the audio and message thread. The goal is to keep the returned object from dangling
/*
AudioProcessor owns a SmartAtomicPtr<T> ptr that the message
thread has public access to.
*/
/* audio thread */ auto* t = ptr.getRaw();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is a dangling pointer now
with getShared(), I believe that t no longer dangles:
/* audio thread */ auto t = ptr.getShared();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is one of 2 shared_ptrs
//holding the previous atomic value of ptr
I ran into some double-deletes, but I believe I have solved them, and also prevented the shared_ptr member from being stomped on in the event you call getShared() and update() at the same time, and also kept it leak-free.
any thoughts?
c++ pointers audio lock-free atomic
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
I am learning about one of the hardest parts of Audio development: the synchronization between the audio thread and the GUI thread. Per the discussion here https://forum.juce.com/t/timur-doumler-talks-on-c-audio-sharing-data-across-threads/26311 and here: https://stackoverflow.com/questions/15460829/lock-free-swap-of-two-unique-ptrt
I'm wondering if the following class solves the problem or comes close to solving it.
template<typename T>
struct SmartAtomicPtr
{
SmartAtomicPtr( T* newT )
{
update( newT );
}
~SmartAtomicPtr()
{
update(nullptr);
}
void update( T* newT, std::memory_order ord = memory_order_seq_cst )
{
keepAlive.reset( atomicTptr.exchange( newT, ord ) );
}
std::shared_ptr<T> getShared(std::memory_order ord = memory_order_seq_cst)
{
return std::make_shared<T>( atomicTptr.load(ord) );
}
T* getRaw(std::memory_order ord = memory_order_seq_cst)
{
return atomicTptr.load(ord);
}
private:
std::atomic<T*> atomicTptr{nullptr};
std::shared_ptr<T> keepAlive;
};
I know that whatever value ends up in the shared_ptr won't be deleted until the SmartAtomicPtr goes out of scope, which is fine.
the ultimate goal would be a lock-free, wait-free solution.
an example of where this might get used is the following interleaving of the audio and message thread. The goal is to keep the returned object from dangling
/*
AudioProcessor owns a SmartAtomicPtr<T> ptr that the message
thread has public access to.
*/
/* audio thread */ auto* t = ptr.getRaw();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is a dangling pointer now
with getShared(), I believe that t no longer dangles:
/* audio thread */ auto t = ptr.getShared();
/* message thread */ processor.ptr.update( new T() );
/* audio thread */ t->doSomething(); //t is one of 2 shared_ptrs
//holding the previous atomic value of ptr
I ran into some double-deletes, but I believe I have solved them, and also prevented the shared_ptr member from being stomped on in the event you call getShared() and update() at the same time, and also kept it leak-free.
any thoughts?
c++ pointers audio lock-free atomic
c++ pointers audio lock-free atomic
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 8 mins ago
200_success
130k16153417
130k16153417
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 13 hours ago
MatkatMusicMatkatMusic
82
82
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
MatkatMusic is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$begingroup$
From C++20, there'sstd::atomic<shared_ptr<T>>partial specialization. You'll want to understand how it works if you're implementing your own.
$endgroup$
– Toby Speight
9 hours ago
add a comment |
$begingroup$
From C++20, there'sstd::atomic<shared_ptr<T>>partial specialization. You'll want to understand how it works if you're implementing your own.
$endgroup$
– Toby Speight
9 hours ago
$begingroup$
From C++20, there's
std::atomic<shared_ptr<T>> partial specialization. You'll want to understand how it works if you're implementing your own.$endgroup$
– Toby Speight
9 hours ago
$begingroup$
From C++20, there's
std::atomic<shared_ptr<T>> partial specialization. You'll want to understand how it works if you're implementing your own.$endgroup$
– Toby Speight
9 hours ago
add a comment |
1 Answer
1
active
oldest
votes
$begingroup$
keepAlive.reset is not thread safe. So your class as a whole cannot be thread safe.
$endgroup$
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
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: "196"
};
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
});
}
});
MatkatMusic is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214829%2fpassing-objects-atomically-across-threads-without-locks-or-data-races-for-audio%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
keepAlive.reset is not thread safe. So your class as a whole cannot be thread safe.
$endgroup$
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
add a comment |
$begingroup$
keepAlive.reset is not thread safe. So your class as a whole cannot be thread safe.
$endgroup$
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
add a comment |
$begingroup$
keepAlive.reset is not thread safe. So your class as a whole cannot be thread safe.
$endgroup$
keepAlive.reset is not thread safe. So your class as a whole cannot be thread safe.
answered 11 hours ago
ratchet freakratchet freak
12k1344
12k1344
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
add a comment |
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
$begingroup$
Concrete proof that a short answer can be a great answer - good one!
$endgroup$
– Toby Speight
9 hours ago
add a comment |
MatkatMusic is a new contributor. Be nice, and check out our Code of Conduct.
MatkatMusic is a new contributor. Be nice, and check out our Code of Conduct.
MatkatMusic is a new contributor. Be nice, and check out our Code of Conduct.
MatkatMusic is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- 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.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214829%2fpassing-objects-atomically-across-threads-without-locks-or-data-races-for-audio%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$begingroup$
From C++20, there's
std::atomic<shared_ptr<T>>partial specialization. You'll want to understand how it works if you're implementing your own.$endgroup$
– Toby Speight
9 hours ago