- negating unsigned.... - 3 Updates
- #include'ing .c files considered harmful? - 3 Updates
- differential reference counting... - 1 Update
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 01:57PM -0800 Take a look at the code here: https://pastebin.com/raw/p1E9WN5i Well there is something stupid I did. The code still works for me, but its still pissing me off. It involves negating an unsigned int. Take a look at the following function: _____________________ void prv_quiesce_begin() { // Try to begin the quiescence process. if (! m_quiesce.exchange(true, std::memory_order_acquire)) { // advance the current collector and grab the old one. unsigned int old = m_current.load(std::memory_order_relaxed) & 0xFU; old = m_current.exchange((old + 1) & 1, std::memory_order_acq_rel); collector& c = m_collectors[old & 0xFU]; // decode reference count. //unsigned int refs = old & 0xFFFFFFF0U; HOLY SHIT!!! long refs = old & 0xFFFFFFF0U; // verify reference count and previous collector index. // RL_ASSERT(!(refs & 0x10U) && (old & 0xFU) == (&c - m_collectors)); // increment and generate an odd reference count. if (c.m_count.fetch_add(refs + 0x10U, std::memory_order_release) == (unsigned int)-refs) { // odd reference count and drop-to-zero condition detected! prv_quiesce_complete(c); } } } _____________________ Now, this makes me feel bad. I should have just wrote it the following way to begin with... Adding UINT_MAX + 1 should negate the reference count without any casts: _____________________ void prv_quiesce_begin() { // Try to begin the quiescence process. if (! m_quiesce.exchange(true, std::memory_order_acquire)) { // advance the current collector and grab the old one. unsigned int old = m_current.load(std::memory_order_relaxed) & 0xFU; old = m_current.exchange((old + 1) & 1, std::memory_order_acq_rel); collector& c = m_collectors[old & 0xFU]; // decode reference count. unsigned int refs = old & 0xFFFFFFF0U; // verify reference count and previous collector index. // RL_ASSERT(!(refs & 0x10U) && (old & 0xFU) == (&c - m_collectors)); // increment and generate an odd reference count. if (c.m_count.fetch_add(refs + 0x10U, std::memory_order_release) == refs + UINT_MAX + 1) { // odd reference count and drop-to-zero condition detected! prv_quiesce_complete(c); } } } _____________________ Much better! refs + UINT_MAX + 1 should equal -refs... ;^) |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 07 02:02PM -0800 On 2/7/2021 1:57 PM, Chris M. Thomasson wrote: > Take a look at the code here: > https://pastebin.com/raw/p1E9WN5i [...] > Much better! > refs + UINT_MAX + 1 should equal -refs... ;^) Also, I need to ensure that I am using actual 32-bit types here. unsigned int can be less than 32-bits. My Bad!! I am correcting these things before I finish creating my "Poor Mans RCU..." example in C++17. The examples work for me, even negating an unsigned int. However, its not portable. |
Richard Damon <Richard@Damon-Family.org>: Feb 07 05:48PM -0500 On 2/7/21 4:57 PM, Chris M. Thomasson wrote: > refs + UINT_MAX + 1 should equal -refs... ;^) UINT_MAX+1 as a unsigned int (which it should be) will be 0, remember unsigned math is mod *_MAX+1 thus refs + UINT_MAX + 1 will be refs. You don't need casts to deal with -refs, as an unsigned it just has the value of UINT_MAX + 1 - refs You only need the cast if you want -refs to be < 0, but I don't see any comparisons in the code that would be affected by that. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 07 01:43PM -0500 On 2/7/21 1:22 PM, Anton Shepelev wrote: > configuration of the several build systems supported by the > project in parallel. What problems, drawbacks, or dangers do > you see to this approach? The answer to your question involves C++ issues, so I've added comp.lang.c++. Note (unrelated to your question): the way I normally do things, "ppscale.c" would already #include "ppscale.h", helping ensure that the declarations in the header file are consistent with the definitions in the .c file. That would render it unnecessary for the C++ file to do so itself. Do you do the same? If you take arbitrary C code, and process it as C++ code, there's a lot of minor issues that could cause problems. See Annex C of the C++ standard for a list of differences that is fairly complete and fairly comprehensive. Most of the differences are likely to prevent compilation, or at least trigger a mandatory diagnostic. Therefore, if he got your code to compile as C++ code with a high warning level and no diagnostics, and in particular, if he thinks he got it to work, then there's a decent chance that none of those problems actually came up. However, there are silent differences - C code that would compile without diagnostics as C++ code, but has subtly different semantics, and if he didn't give the code a thorough test, he might have missed those differences. It would be far safer to compile it as C code, and then use extern "C" declarations to link to it from C++ code. There's far fewer tricky issues to worry about (though there's still a few). |
Anton Shepelev <anton.txt@gmail.com>: Feb 07 09:57PM +0300 James Kuyper: > The answer to your question involves C++ issues, so I've > added comp.lang.c++. Yes, C++ programmers are welcome. > are consistent with the definitions in the .c file. That > would render it unnecessary for the C++ file to do so > itself. Do you do the same? No: https://launchpad.net/ppscale but I will, which will make including ppscale.h redundant. I don't know why I didn't do it, probably just forgot. I kept thinking of .c and .h files as the interface and implentation parts of a Modula module, which they are not. Thanks for the suggestion. > that is fairly complete and fairly comprehensive. Most of > the differences are likely to prevent compilation, or at > least trigger a mandatory diagnostic. That is a good reason to compile the C code with a C compliler into a separate object file or static library. > use extern "C" declarations to link to it from C++ code. > There's far fewer tricky issues to worry about (though > there's still a few). Thank you very much for the advice. I will forward it to the maintainer. -- () ascii ribbon campaign -- against html e-mail /\ http://preview.tinyurl.com/qcy6mjc [archived] |
Manfred <noname@invalid.add>: Feb 07 09:04PM +0100 On 2/7/21 7:57 PM, Anton Shepelev wrote: > kept thinking of .c and .h files as the interface and > implentation parts of a Modula module, which they are not. > Thanks for the suggestion. While you're at it, you may want to bracket the C declarations in the header file with #ifdef __cplusplus extern "C" {
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment