Am 11.09.2024 um 12:15 schrieb [email protected]:
I've been looking at counting_semaphore and it looks useful but something
that doesn't seem to be properly explained anywhere is the template
parameter value. eg you can do:
std::counting_semaphore sem(2)
which will let a max of 2 threads into the protected block at a time or:
std::counting_semaphore<some number> sem(2)
such as
std::counting_semaphore<10> sem(2)
I don't understand what the '10' will do. ..
The ten gives an upper limit beyond the semaphore wont't increment.
Usually you won't need a C++20 semaphore yourself. For most purpose
the mutex and the condition_variable is sufficient.
Am 11.09.2024 um 14:03 schrieb [email protected]:
What upper limit? The max number of threads allowed in the protected section >> above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting >> and ignore any beyond that? What happens if thread 11 comes along?
The static parmeter is the maximum counter and the the two is the
initial counter. So two threads can currently acquire that semaphore.
Condition variables IMO are unintuitive (eg the internal state change from >> waiting on condition variable to waiting on mutex is completely invisible) >> and hence very prone to logical bugs. I tend to avoid them where possible.
If you have a producer-consumer-pattern condition variables are the most >efficient way to handle this pattern.
Am 11.09.2024 um 14:29 schrieb [email protected]:
On Wed, 11 Sep 2024 14:10:05 +0200
The static parmeter is the maximum counter and the the two is the
initial counter. So two threads can currently acquire that semaphore.
Sorry, I still don't get it. What do you mean by maximum counter?
If you have a maximum counter of ten and an initial counter of two
you may increment the counter further eight times until another
release doesn't increment the counter.
On Wed, 11 Sep 2024 14:10:05 +0200
Bonita Montero <[email protected]> boringly babbled:
Am 11.09.2024 um 14:03 schrieb [email protected]:
What upper limit? The max number of threads allowed in the protected section
above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
and ignore any beyond that? What happens if thread 11 comes along?
The static parmeter is the maximum counter and the the two is the
initial counter. So two threads can currently acquire that semaphore.
Sorry, I still don't get it. What do you mean by maximum counter?
Maximum threads that can wait on the semaphore and 11 gets an error?
Maximum threads that can ever access the protected section and after 10 have accessed it the section is blocked to all threads?
Condition variables IMO are unintuitive (eg the internal state change from >>> waiting on condition variable to waiting on mutex is completely invisible) >>> and hence very prone to logical bugs. I tend to avoid them where possible. >>If you have a producer-consumer-pattern condition variables are the most
efficient way to handle this pattern.
Efficient maybe, but the code can be obtuse and debugging a pain.
I've been looking at counting_semaphore and it looks useful but something that doesn't seem to be properly explained anywhere is the template
parameter value. eg you can do:
std::counting_semaphore sem(2)
which will let a max of 2 threads into the protected block at a time or:
I don't understand what the '10' will do. Its returned by the max()
method but whats its purpose since if its the maximum possible threads
you could have in the protected block it makes no sense because you can't change that value after creation as far as I can see.
On 09/11/24 3:15 AM, [email protected] wrote:
I've been looking at counting_semaphore and it looks useful but something
that doesn't seem to be properly explained anywhere is the template
parameter value. eg you can do:
std::counting_semaphore sem(2)
which will let a max of 2 threads into the protected block at a time or:
No, there's nothing "max" about that 2 here. 2 means that the semaphore
will be created with 2 available "permissions to enter" (permissions to >`acquire()`) initially. The number of available "permissions" can be >increased by calling `release()` after creating the semaphore. Call >`release()` 3 more times on our semaphore right away, and the initial 2
will increase to 5. So, 2 is not "max".
The "max" is set by the template parameter `LeastMaxValue`.
I don't understand what the '10' will do. Its returned by the max()
method but whats its purpose since if its the maximum possible threads
you could have in the protected block it makes no sense because you can't
change that value after creation as far as I can see.
The purpose of the template `LeastMaxValue` parameter is to let the >implementation choose the best representation for the internal counter.
Am 11.09.2024 um 17:03 schrieb [email protected]:
On Wed, 11 Sep 2024 07:37:13 -0700
Andrey Tarasevich <[email protected]> boringly babbled:
On 09/11/24 3:15 AM, [email protected] wrote:
I've been looking at counting_semaphore and it looks useful but something >>>> that doesn't seem to be properly explained anywhere is the templateNo, there's nothing "max" about that 2 here. 2 means that the semaphore
parameter value. eg you can do:
std::counting_semaphore sem(2)
which will let a max of 2 threads into the protected block at a time or: >>>
will be created with 2 available "permissions to enter" (permissions to
`acquire()`) initially. The number of available "permissions" can be
increased by calling `release()` after creating the semaphore. Call
`release()` 3 more times on our semaphore right away, and the initial 2
will increase to 5. So, 2 is not "max".
The "max" is set by the template parameter `LeastMaxValue`.
It seems I'm not the only one getting confused here. If I write:
std::counting_semaphore<10> sem(2)
then the semaphore can only be aquired TWO times, not 10. I don't understand >> what the 10 is supposed to do as changing the 10 to 0,1 or 1000 makes no
difference whatsoever to how many times acquire() can be called before
release() is called in the tests I've done.
10 is the maximum count the semaphore is allowed to reach, therefore >binary_semaphore, which is an alias-template to counting_semaphore<1>,
has a maximum count of one.
Am 11.09.2024 um 18:04 schrieb [email protected]:
We're going around in circles. Instead of reading the man page how about
trying some code. How many times to you think this loop will run before it >> hangs? 100 or 2?
#include <stdio.h>
#include <semaphore>
std::counting_semaphore<100> sem(2);
int main()
{
for(int i=0;;++i)
{
sem.acquire();
printf("Acquired %d\n",i);
}
return 0;
}
Answer: 2
There's nothing wrong with what I said. Once the semaphore is created
its maximum count isn't relevant any more. The return statement isn't
On Wed, 11 Sep 2024 07:37:13 -0700
Andrey Tarasevich <[email protected]> boringly babbled:
On 09/11/24 3:15 AM, [email protected] wrote:
I've been looking at counting_semaphore and it looks useful but something >>> that doesn't seem to be properly explained anywhere is the template
parameter value. eg you can do:
std::counting_semaphore sem(2)
which will let a max of 2 threads into the protected block at a time or:
No, there's nothing "max" about that 2 here. 2 means that the semaphore
will be created with 2 available "permissions to enter" (permissions to
`acquire()`) initially. The number of available "permissions" can be
increased by calling `release()` after creating the semaphore. Call
`release()` 3 more times on our semaphore right away, and the initial 2
will increase to 5. So, 2 is not "max".
The "max" is set by the template parameter `LeastMaxValue`.
It seems I'm not the only one getting confused here. If I write:
std::counting_semaphore<10> sem(2)
then the semaphore can only be aquired TWO times, not 10.
On 09/11/24 8:03 AM, [email protected] wrote:
then the semaphore can only be aquired TWO times, not 10.
Are you trying to troll people or what?
If you write
std::counting_semaphore<10> sem(2);
then the semaphore can be acquired 2 times. But it can also be released >instead at least 8 times, after which it can be acquired 10 times.
See the math? 2 + 8 = 10?
The 10 is the "least" max value, meaning that the implementation has to
let you release your freshly created `sem` _at_ _least_ 8 times, but can
also permit you to release, say, a 1000 or more times.
[email protected] writes:
Sorry, I still don't get it. What do you mean by maximum counter?
You might want to consider who you are talking to.
The template parameter M is very different and rather unusual. It is,
But this "limit" is not enforced other than by making the behaviour
undefined when it is exceeded. Pre-conditions on the operations state
On Wed, 11 Sep 2024 14:10:05 +0200
Bonita Montero <[email protected]> boringly babbled:
Am 11.09.2024 um 14:03 schrieb [email protected]:
What upper limit? The max number of threads allowed in the protected section
above is 2, not 10. Or do you mean it'll only count up to 10 threads waiting
and ignore any beyond that? What happens if thread 11 comes along?
The static parmeter is the maximum counter and the the two is the
initial counter. So two threads can currently acquire that semaphore.
Sorry, I still don't get it. What do you mean by maximum counter?
On Wed, 11 Sep 2024 20:56:12 -0700
Andrey Tarasevich <[email protected]> boringly babbled:
On 09/11/24 8:03 AM, [email protected] wrote:
then the semaphore can only be aquired TWO times, not 10.
Are you trying to troll people or what?
I get REALLY sick of people who think someone who's asking a question that they know the answer to as trolling.
If you write
std::counting_semaphore<10> sem(2);
then the semaphore can be acquired 2 times. But it can also be released
instead at least 8 times, after which it can be acquired 10 times.
Thank you. You've explained in 2 lines what no one else managed.
See the math? 2 + 8 = 10?
No need to be patronising though thats par for the course on this group.
The 10 is the "least" max value, meaning that the implementation has to
let you release your freshly created `sem` _at_ _least_ 8 times, but can
also permit you to release, say, a 1000 or more times.
Sounds profoundly useless but at least now I know. Though I can't imagine when I'd ever use it.
Sounds profoundly useless but at least now I know. Though I can't imagine when I'd ever use it.
On 09/12/24 4:00 AM, [email protected] wrote:
Clang seems to ignore it. You can call release() as much as you like and
it'll just keep increasing the counter.
It "ignores" it exactly the same way as the following declaration
std::uint_fast8_t n = 2;
might "ignore" the 8 in the type name and allow you to increment the
variable well past 255. Come to think of it, the underlying reasons for
It is perfectly explained in the spec. And it's been thoroughly
Clang seems to ignore it. You can call release() as much as you like and it'll just keep increasing the counter.
On 12/09/2024 09:43, [email protected] wrote:
On Wed, 11 Sep 2024 20:56:12 -0700
Andrey Tarasevich <[email protected]> boringly babbled:
On 09/11/24 8:03 AM, [email protected] wrote:
then the semaphore can only be aquired TWO times, not 10.
Are you trying to troll people or what?
I get REALLY sick of people who think someone who's asking a question that >> they know the answer to as trolling.
You already accused everyone else in the thread of not knowing what they
are talking about. Let's try to keep things light.
It is not immediately obvious why this template parameter exists. The
answer is the internal implementation of the semaphore, which requires a >queue of blocked threads. A binary semaphore has a maximum of 1, and
may be implemented more efficiently than a counting semaphore with a
higher maximum. For a low maximum, the queue might be implemented as a >std::array<> of the appropriate size. For a higher maximum, perhaps the >implementation uses a std::vector<>. So you pick the template parameter
here to be at least as big as you will ever need for the semaphore, but
aim to be as small as you can.
On Thu, 12 Sep 2024 07:34:23 -0700
Andrey Tarasevich <[email protected]> boringly babbled:
On 09/12/24 4:00 AM, [email protected] wrote:
Clang seems to ignore it. You can call release() as much as you like and >>> it'll just keep increasing the counter.
It "ignores" it exactly the same way as the following declaration
std::uint_fast8_t n = 2;
might "ignore" the 8 in the type name and allow you to increment the
variable well past 255. Come to think of it, the underlying reasons for
Incrementing integrals beyond their max value can have valid uses.
A method
allowing you to increment a counter beyond the apparent max counter value - not so much.
It is perfectly explained in the spec. And it's been thoroughly
LOL! Ah, a comedian has joined us!
On 12/09/2024 16:53, [email protected] wrote:
might "ignore" the 8 in the type name and allow you to increment the
variable well past 255. Come to think of it, the underlying reasons for
Incrementing integrals beyond their max value can have valid uses.
No, it cannot.
It is perfectly explained in the spec. And it's been thoroughly
LOL! Ah, a comedian has joined us!
It certainly makes sense in the page at
<https://en.cppreference.com/w/cpp/thread/counting_semaphore>
But for some reason you have moved onto /wilful/ ignorance - you are >determined to ignore the information you have been given, to argue with
an insult people trying to help you, and to deride the whole concept. I >really don't get it. Did you want to know about the template parameter
or not?
On Fri, 13 Sep 2024 08:39:50 +0200
David Brown <[email protected]> boringly babbled:
On 12/09/2024 16:53, [email protected] wrote:
might "ignore" the 8 in the type name and allow you to increment theIncrementing integrals beyond their max value can have valid uses.
variable well past 255. Come to think of it, the underlying reasons for >>>
No, it cannot.
Clearly you've never done any low level networking where id fields are fixed sized and will eventually wrap. Eg, TCP sequence number. I'm sure there are
a myriad of other examples.
It is perfectly explained in the spec. And it's been thoroughly
LOL! Ah, a comedian has joined us!
It certainly makes sense in the page at
<https://en.cppreference.com/w/cpp/thread/counting_semaphore>
If you think thats clear I'd hate to see what you consider obtuse.
But for some reason you have moved onto /wilful/ ignorance - you are
determined to ignore the information you have been given, to argue with
an insult people trying to help you, and to deride the whole concept. I
really don't get it. Did you want to know about the template parameter
or not?
Or alternatively some people just can't explain things very well. 2 people managed it - you and the others didn't.
Am 13.09.2024 um 15:21 schrieb [email protected]:
Oh right, so for 32 bit TCP seq number instead of just doing:
++tcp->seq_num;
which would autonatically wrap after 2^32, in your world we'd have do to:
tcp->seq_num = (uint32_t)(((uint_64_t)tcp->seq_num + 1) % 0x100000000L);
Really?
Don't be an ass.
I've also not seen any meaningful code which shows what this
maximum is good for .... But what sense should a wrap-around
make with a semaphore ??? A semaphore should remember all its
releases if possible.
On 13/09/2024 09:26, [email protected] wrote:
Clearly you've never done any low level networking where id fields are fixed >> sized and will eventually wrap. Eg, TCP sequence number. I'm sure there are >> a myriad of other examples.
Clearly you can make up a complete load of drivel with no basis in reality.
So let me be /clear/ here. There is /no/ valid use of incrementing
something beyond its maximum value. The whole concept makes no sense.
There /are/ lots of valid uses of wrapping types. Sequence numbers in >low-level networking would be one example of that - one which I /have/
used countless times in my work. But that is not incrementing beyond a
max value - it is using a modulo wrapping increment to give a result
/within/ the valid range, not beyond it.
If you think thats clear I'd hate to see what you consider obtuse.
Have you ever considered that /you/ might be the problem here? Other
people seem to understand it fine. Consider the common factor in all
your difficulties understanding the template parameter.
But does all this mean that you now understand what the integer template >parameter is for, and what it does? And do you understand how to use
the counting semaphore? If so, that's great.
On Thu, 12 Sep 2024 07:34:23 -0700
Andrey Tarasevich <[email protected]> boringly babbled:
On 09/12/24 4:00 AM, [email protected] wrote:
Clang seems to ignore it. You can call release() as much as you like and >>> it'll just keep increasing the counter.
It "ignores" it exactly the same way as the following declaration
std::uint_fast8_t n = 2;
might "ignore" the 8 in the type name and allow you to increment the
variable well past 255. Come to think of it, the underlying reasons for
Incrementing integrals beyond their max value can have valid uses. A method allowing you to increment a counter beyond the apparent max counter value - not so much.
On Fri, 13 Sep 2024 12:54:53 +0200
David Brown <[email protected]> boringly babbled:
On 13/09/2024 09:26, [email protected] wrote:
Clearly you've never done any low level networking where id fields are fixed
sized and will eventually wrap. Eg, TCP sequence number. I'm sure there are >>> a myriad of other examples.
Clearly you can make up a complete load of drivel with no basis in reality.
Oh dear, someones been caught out and is throwing his toys out the pram.
So let me be /clear/ here. There is /no/ valid use of incrementing
something beyond its maximum value. The whole concept makes no sense.
Bollocks.
There /are/ lots of valid uses of wrapping types. Sequence numbers in
low-level networking would be one example of that - one which I /have/
used countless times in my work. But that is not incrementing beyond a
max value - it is using a modulo wrapping increment to give a result
/within/ the valid range, not beyond it.
Oh right, so for 32 bit TCP seq number instead of just doing:
++tcp->seq_num;
which would autonatically wrap after 2^32, in your world we'd have do to:
tcp->seq_num = (uint32_t)(((uint_64_t)tcp->seq_num + 1) % 0x100000000L);
Really?
Don't be an ass.
If you think thats clear I'd hate to see what you consider obtuse.
Have you ever considered that /you/ might be the problem here? Other
people seem to understand it fine. Consider the common factor in all
your difficulties understanding the template parameter.
If it wasn't so vague I wouldn't have needed to ask the question.
But does all this mean that you now understand what the integer template
parameter is for, and what it does? And do you understand how to use
the counting semaphore? If so, that's great.
Aww bless, so kind.
On 13/09/2024 15:21, [email protected] wrote:
Oh right, so for 32 bit TCP seq number instead of just doing:
++tcp->seq_num;
which would autonatically wrap after 2^32, in your world we'd have do to:
tcp->seq_num = (uint32_t)(((uint_64_t)tcp->seq_num + 1) % 0x100000000L);
Really?
Don't be an ass.
What /are/ you talking about? Do you even know how arithmetic works in
C++ ?
If you have "uint32_t seq_num = 0xffffffff;", then write "seq_num++;",
you are /not/ "incrementing beyond its maximum value". You are
incrementing modulo 2 ^ 32, because that's how the operation works in C++.
And if you have "int32_t seq_num;" and are using "++" to increment it
and think you have wrapping, then you are writing crap code.
Aww bless, so kind.
You really are a poor excuse for a human being.
Am 13.09.2024 um 21:44 schrieb Chris M. Thomasson:
I am talking about a condvar/mutex based queue vs a lock-free, or even
"mostly" wait-free queue under heavy contention... Which one is going to
be more efficient?
Lock-free queues are inefficient because they've to be polled.
Am 14.09.2024 um 11:18 schrieb [email protected]:
On Sat, 14 Sep 2024 01:43:26 +0200
Bonita Montero <[email protected]> gabbled:
Am 13.09.2024 um 21:44 schrieb Chris M. Thomasson:
I am talking about a condvar/mutex based queue vs a lock-free, or
even "mostly" wait-free queue under heavy contention... Which one is
going to be more efficient?
Lock-free queues are inefficient because they've to be polled.
Everything has to be polled at some level except hardware interrupt based
code.
If the queue is empty CPU-time is usually handed voluntary to
another thread - not with a lock-free-queue.
Am 14.09.2024 um 12:58 schrieb [email protected]:
Unless the locking mechanism is implemented in hardware then software
has to manage it whether in user space or kernel space.
The fast-path is implemented in hardware through the support of atomics.
Am 14.09.2024 um 17:13 schrieb [email protected]:
An assembler opcode , even a single one like x86 CMPXCHG, is still
software.
The implementatoin of this opcode is hardware.
Am 14.09.2024 um 17:48 schrieb [email protected]:
Its probably implemented in microcode just like all the others but even if >> it wasn't, so what? Its still software.
It needs an atomic read-modify-write cycle, that's not possible with >microcode but a cache-subsystem that supports this.
Am 14.09.2024 um 17:55 schrieb [email protected]:
Microcode has full control of the hardware. If it needs to immediately
lock all cache memory it can.
If the cache doesn't support atomic read-modify-write cycles a different >microcode doesn't help. The caching-logic itself is not controlle by >microcode.
Am 15.09.2024 um 11:05 schrieb [email protected]:
If the cache doesn't support it then nothing will help including hardThe point was that how the cache works isn't controlled my microcode.
wired TTL logic in the CPU or whatever automagical solution you think
works. Microcode exists to operate the hardware at the lowest level,
thats its entire purpose.
But your statement was that read-modify-write cycles are enabled by >microcode.
Am 15.09.2024 um 11:52 schrieb [email protected]:
All CPUs are different, ...
A microcode-contolled cache would be too slow. Such instructions
are hardwired for sure.
Am 13.09.2024 um 15:21 schrieb [email protected]:
Oh right, so for 32 bit TCP seq number instead of just doing:
++tcp->seq_num;
which would autonatically wrap after 2^32, in your world we'd have do to:
tcp->seq_num = (uint32_t)(((uint_64_t)tcp->seq_num + 1) % 0x100000000L);
Really?
Don't be an ass.
I've also not seen any meaningful code which shows what this
maximum is good for ....
But what sense should a wrap-around
make with a semaphore ??? A semaphore should remember all its
releases if possible.
Am 15.09.2024 um 11:52 schrieb [email protected]:
All CPUs are different, ...
A microcode-contolled cache would be too slow. Such instructions
are hardwired for sure.
Am 15.09.2024 um 11:05 schrieb [email protected]:
If the cache doesn't support it then nothing will help including hardThe point was that how the cache works isn't controlled my microcode.
wired TTL logic in the CPU or whatever automagical solution you think
works. Microcode exists to operate the hardware at the lowest level,
thats its entire purpose.
But your statement was that read-modify-write cycles are enabled by >microcode.
On 9/11/2024 7:23 AM, David Brown wrote:
On 11/09/2024 14:29, [email protected] wrote:
On Wed, 11 Sep 2024 14:10:05 +0200
Bonita Montero <[email protected]> boringly babbled:
Am 11.09.2024 um 14:03 schrieb [email protected]:
What upper limit? The max number of threads allowed in the
protected section
above is 2, not 10. Or do you mean it'll only count up to 10
threads waiting
and ignore any beyond that? What happens if thread 11 comes along?
The static parmeter is the maximum counter and the the two is the
initial counter. So two threads can currently acquire that semaphore.
Sorry, I still don't get it. What do you mean by maximum counter?
Maximum threads that can wait on the semaphore and 11 gets an error?
Maximum threads that can ever access the protected section and after
10 have
accessed it the section is blocked to all threads?
You are talking about a counting semaphore here - the number will be
the maximum value of the count. (The actual maximum value could be
bigger than the template parameter, but not smaller than it.) If this
maximum value is 10, then you can acquire the semaphore 10 times
without blocking - any future acquires will block until there are
releases.
Semaphores can be acquired and released by any threads - one thread
can acquire often, another thread can release them, or you can have
any combination. They are not used for protection sections or data -
they are used as signalling mechanisms. One or more "producer" thread
might make objects, and one or more "consumer" threads used them, in
which case your 10 here is the maximum number of these objects that
will be buffered up at a time.
[...]
Think of creating a queue with 100,000 elements in it. The semaphore to protect this queue should have an initial state of 100,000. The least
min value, should be high because the queue might have 1.9 million
elements in there. So, for this queue:
std::counting_semaphore<PTRDIFF_MAX> sem(100000);
right? There are 100000 elements in the queue because its initialized
that way. A single thread can pop and work on 100000 elements before it blocks on a queue empty condition.
On 9/17/2024 12:22 AM, David Brown wrote:
On 16/09/2024 23:22, Chris M. Thomasson wrote:
On 9/11/2024 7:23 AM, David Brown wrote:
On 11/09/2024 14:29, [email protected] wrote:
On Wed, 11 Sep 2024 14:10:05 +0200
Bonita Montero <[email protected]> boringly babbled:
Am 11.09.2024 um 14:03 schrieb [email protected]:Sorry, I still don't get it. What do you mean by maximum counter?
What upper limit? The max number of threads allowed in theThe static parmeter is the maximum counter and the the two is the
protected section
above is 2, not 10. Or do you mean it'll only count up to 10
threads waiting
and ignore any beyond that? What happens if thread 11 comes along? >>>>>>
initial counter. So two threads can currently acquire that semaphore. >>>>>
Maximum threads that can wait on the semaphore and 11 gets an error? >>>>> Maximum threads that can ever access the protected section and
after 10 have
accessed it the section is blocked to all threads?
You are talking about a counting semaphore here - the number will be
the maximum value of the count. (The actual maximum value could be
bigger than the template parameter, but not smaller than it.) If
this maximum value is 10, then you can acquire the semaphore 10
times without blocking - any future acquires will block until there
are releases.
Semaphores can be acquired and released by any threads - one thread
can acquire often, another thread can release them, or you can have
any combination. They are not used for protection sections or data
- they are used as signalling mechanisms. One or more "producer"
thread might make objects, and one or more "consumer" threads used
them, in which case your 10 here is the maximum number of these
objects that will be buffered up at a time.
[...]
Think of creating a queue with 100,000 elements in it. The semaphore
to protect this queue should have an initial state of 100,000. The
least min value, should be high because the queue might have 1.9
million elements in there. So, for this queue:
std::counting_semaphore<PTRDIFF_MAX> sem(100000);
right? There are 100000 elements in the queue because its initialized
that way. A single thread can pop and work on 100000 elements before
it blocks on a queue empty condition.
Roughly yes - assuming you are setting up the queue with the first
100,000 elements and then creating the semaphore, then allowing the
queue to grow or shrink unhindered. It's more common for queues to
start with a semaphore of count 0 (an empty queue) and then add
elements, but if you have 100,000 elements in advance then this would
be a more efficient initialisation.
I sure think so. :^)
You can also omit the template parameter, in which case an
implementation-defined default is used. A quick test on godbolt's gcc
shows that this gives a max() of 0x7fff'ffff, and that this is the
largest value supported by the C++ library used by that implementation
- it keeps the count as a signed 32-bit integer. Attempting to use
PTRDIFF_MAX triggers a static assertion:
static_assert(__least_max_value <= __semaphore_impl::_S_max);
Oh shit! I assumed setting it to PTRDIFF_MAX is okay. Shit! Well, damn. thanks for the info David. Sometimes I think the template parameter is
there for specialization purposes ala binary semaphore with its template param as 1.
I don't know if this is a conformance flaw in the C++ standard
library, or if I just haven't read the documentation details well
enough. And I couldn't see any specification for what the default
value should be, but I can't think of any other reasonable choice than
the biggest acceptable value.
Agreed. Again, thanks for the info. :^)
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 715 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 02:59:50 |
| Calls: | 12,098 |
| Calls today: | 6 |
| Files: | 15,003 |
| Messages: | 6,517,869 |