[erlang-bugs] R11B-2 SMP Timer Race Condition Bug [Re: bug in timer:sleep/1 smp implementation (R11B-0)]
Dmitriy Kargapolov
dmitry.kargapolov@REDACTED
Fri Dec 22 20:52:27 CET 2006
Unfortunately I can not create standalone test for this bug, even when I
became much more close to understanding the effect.
This bug appears only in highly loaded system.
Recently I did manage to trace some points in the code and see at least
one scenario for the race condition bug.
1. Thread A erl_set_timer (time.c) Lock Timing Wheel
2. Thread A insert_timer (time.c) Insert Timer T1
3. Thread A erl_set_timer (time.c) Unlock Timing Wheel
4. Thread B bump_timer_internal (time.c) Lock Timing Wheel
5. Thread A cancel_timer (erl_process.c) Cancel timer T1
6. Thread B bump_timer_internal (time.c) Build list of Expired
Timers
7. Thread A erl_cancel_timer (time.c) Cancel timer T1:
Waiting for Timing Wheel Lock
8. Thread B bump_timer_internal (time.c) Unlock Timing Wheel
9. Thread C set_timer (erl_process.c) New Timeout Request (T2)
10. Thread B bump_timer_internal (time.c) Call Expired Timers
Callbacks
11. Thread B free_ptimer (utils.c) Timer T1 callback
invokes free_ptimer()
12. Thread C erts_create_smp_ptimer (utils.c) Create Timer
ErtsSmpPTimer for T2
13. Thread B free_ptimer (utils.c) Free ErtsSmpPTimer
memory block
14. Thread C erts_create_smp_ptimer (utils.c) Allocate ErtsSmpPTimer
for T2, block reused!
15. Thread C erl_set_timer (time.c) erl_set_timer invoked
for T2
16. Thread C erl_set_timer (time.c) Lock Timing Wheel
17. Thread C insert_timer (time.c) Insert Timer T2
18. Thread C erl_set_timer (time.c) Unlock Timing Wheel
19. Thread A erl_cancel_timer (time.c) Lock Timing Wheel
20. Thread A erl_cancel_timer (time.c) Remove ex-T1 == T2
from the timing wheel
21. Thread A erl_cancel_timer (time.c) Unlock Timing Wheel
See also attached diagram.
Looks like one more mutex required, excluding release of ErtsSmpPTimer
memory block by timeout callback if cancel request was issued for the
timer and vise versa. The two point of control - cancel timer and timer
expiration should not interfere.
This bug happens only in SMP mode since there additional timer control
structure ErtsSmpPTimer is used between emulator and timing wheel.
Mikael Pettersson wrote:
> Dmitriy Kargapolov writes:
> >
> > When running erl with -smp +S 2 option, sometimes process gets stuck in
> > timer:sleep/1.
> > Process code looks like:
> >
> > some_receiver(State) ->
> > NewState = receive
> > % legal packet
> > {some_keyword, Address, Port, Packet} ->
> > State1 = handle_packet(Address, Port, Packet, State),
> > timer:sleep(get_loop_delay()),
> > State1;
> > % unknown message
> > _ ->
> > State
> > end,
> > some_receiver(NewState).
> >
> > Delay value varies in range 1..999
> >
> > Since timer:sleep/1 implemented as:
> > sleep(T) ->
> > receive
> > after T -> ok
> > end.
> > it seems to be problem with "after" in smp implementation in R11B-0
> >
> > I don't have more details yet but will continue testing.
> > My platform: 2.6.9-5.ELsmp #1 SMP i686 i686 i386 GNU/Linux
>
> Interesting. Please send us a small standalone module that exhibits
> the bug, and I'll see if I can reproduce it.
>
> /Mikael
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: RaceCond.pdf
Type: application/pdf
Size: 16115 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20061222/b1790c40/attachment.pdf>
More information about the erlang-bugs
mailing list