Subject: Re: [boost] [asio] Bug: Handlers execute on the wrong strand (Gavin Lambert).
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2013-10-30 22:23:56
On 31/10/2013 14:12, Quoth Niall Douglas:
> From what I can tell ASIO uses Win32 critical sections which come
> with spin counts. If you keep every operation under the count, all is
> good, else you get spikes as it drops to kernel wait.
I also tried replacing the locks with some of my own (which are slower
but handle PI) but it didn't make much difference. This isn't
surprising though as the times I was seeing were in the order of 300ms
from requesting the lock to being granted it, as I said before, which is
a bit excessive for even a kernel wait. (And before you ask, the
handlers themselves don't take that long to run -- I don't have precise
figures handy ATM but generally I consider them slow if they take 5ms.
Though of course Windows being Windows there can be 15ms spikes if it
does hit a kernel wait or similar; still nowhere close to 300ms though.)
I still wouldn't rule out "I was doing something silly in my code" of
course (there's always room for that), and I'm probably operating
outside of what ASIO was originally intended for anyway (since I'm not
doing sockets). But whatever was causing it must have either been in
ASIO itself or in the small amount of wrapper code I had to rewrite when
moving from ASIO to my custom implementation, because it seems to have
gone away since switching over. (The access pattern of the outside code
> I might know something about nedmalloc :)
Funny that. :)
> Mmm, I was just about to suggest that nedmalloc might be doing a free
> space consolidation run and that might be the cause of the spike, but
> if it isn't then okay.
Not unless it can do that without locking anything, at least. I was
basically only recording attempts to lock/unlock rather than any access
to the allocator.
I suspect I'm hitting the memory allocator in my implementation more
frequently than ASIO was, actually -- I'm not trying to cache and reuse
operations or buffers; it just does a "new" whenever it needs it.
(Although I might be getting away with fewer intermediate objects, since
I've cut the functionality to the bare minimum.) So I doubt allocation
was the issue. (Unless maybe it was trying to *avoid* allocation that
introduced the issue, as the post that started this discussion implied.)