Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Possibly, taking advantage of blocking...

30 views
Skip to first unread message

Chris M. Thomasson

unread,
Mar 9, 2017, 4:03:00 PM3/9/17
to
For now, lets start off with taking a simple case of a try_lock
operation failing on a mutex. What if we tried to do something else
while we had to wait anyway?

Think of all those mutex lock operations? Can they be converted into
little message pumps in and of themselves? Fwiw, here is some very
contrived pseudo code, that just scratches the surface of this possible
line of thinking:
____________________________________
for (;;)
{
if (try_lock()) return;

if (! try_something_else())
{
// possible nesting opportunity...
lock();
return;
}
}
____________________________________


We try to lock the mutex to perform work under its protection. If that
action succeeds we exit the for loop. If not, we try to do something
else, this can be recursive up to a limit. If we actually did some work
wrt trying something else, we repeat the process wrt the for(;;) loop,
trying the original mutex lock again. However, if no other work could be
found, we just block for the locking action of the mutex, and wait for
it be committed, and exit from the loop. AFAICT, this is a sort of "odd
message pump" in a sense, with an adaptive mutex flare.

The key aspect is that the mutex is locked when this for(;;) loop exits.
Ready for the caller to use.

Humm..

Any thoughts?

Is this crap? It cannot be anything new. But, it would be nice to talk
about threading here for C++ can handle it now.

Nice! :^)

Chris M. Thomasson

unread,
Mar 12, 2017, 3:07:37 AM3/12/17
to
I hope the thought did not come across as stupid, but can we have a
discussion on this? How do you handle blocking?

Paavo Helde

unread,
Mar 12, 2017, 4:19:59 AM3/12/17
to
In my programs I strive to make mutex lock durations as short as
possible. Typically just a pointer will be added or removed from a queue
during the lock. Therefore the mutex would become available very soon
and there would be no point to try anything else during that time.

Having long lock times and trying to carry out other tasks while waiting
for the lock seems like a sure receipt for over-complicating the system,
increasing the danger of deadlocks and decreasing the responsiveness of
the program. YMMV.



Chris M. Thomasson

unread,
Mar 12, 2017, 4:49:01 AM3/12/17
to
long wait times should be avoided. However, think about how short wait
times should gain the lock in step 0 more often than not.
The slow path fallback is step 2:
_____________________________________
for (;;)
{
0: if (try_lock()) return;

1: if (! try_something_else())
{
// possible nesting opportunity...
2: lock();
3: return;
}
}
_____________________________________

Not sure about deadlocks yet, should not be a problem if we know some
things about the nature of step 1. This can be modeled wrt making step 1
random. Sometimes it has some work to do, other times it does not. When
not, it falls back to the slow path in step 2.

There should be a limit on the for (;;) to prevent infinite loop wrt
always having other work to do, and always failing the try lock.

So, perhaps something like:
_______________________________________
for (unsigned int i = 0; i < 42; ++i)
{
if (try_lock()) return;

if (! try_something_else())
{
break;
}
}

lock();
return;
_______________________________________


Trying to think of a contrived usage case here.


;^)

Chris M. Thomasson

unread,
Mar 13, 2017, 6:54:53 PM3/13/17
to
On 3/12/2017 12:19 AM, Paavo Helde wrote:
Try to put mutex queue under sustained pressure. Then take a look at the
fast-path vs slow-paths, it does not scale that well. The lock based
queue can fall apart under blocking. The adaptive nature of some mutexs
will spin before hitting the kernel for a real blocking wait. The little
algorithm I laid out is like an adaptive mutex in a sense, except
instead of spin wait, it tries to do other work.

Chris M. Thomasson

unread,
Mar 19, 2017, 10:30:58 PM3/19/17
to
On 3/9/2017 1:02 PM, Chris M. Thomasson wrote:
> For now, lets start off with taking a simple case of a try_lock
> operation failing on a mutex. What if we tried to do something else
> while we had to wait anyway?
>
> Think of all those mutex lock operations? Can they be converted into
> little message pumps in and of themselves? Fwiw, here is some very
> contrived pseudo code, that just scratches the surface of this possible
> line of thinking:
> ____________________________________
> for (;;)
> {
> if (try_lock()) return;
>
> if (! try_something_else())
> {
> // possible nesting opportunity...
> lock();
> return;
> }
> }
> ____________________________________
[...]

> _______________________________________
> for (unsigned int i = 0; i < 42; ++i)
> {
> if (try_lock()) return;

> if (! try_something_else())
> {
> break;
> }
> }

> lock();
> return;
> _______________________________________


Think of the call to (try_something_else()) as trying to acquire work
from another queue... It can process 42 items before it falls back to
actually performing a blocking all-in wait, call to lock...

Any thoughts?


0 new messages