On Sun, 19 Jan 2025, Takashi Yano wrote:

> Thanks for pointing out this. You are right if othre threads may
> set current_sig to non-zero value. Current cygwin sets current_sig
> to non-zero only in
> _cygtls::interrupt_setup()
> and
> _cygtls::handle_SIGCONT()
> both are called from sigpacket::process() as follows.
>
> wait_sig()->
>  sigpacket::process() +-> sigpacket::setup_handler() -> 
> _cygtls::interrupt_setup()
>                       \-> _cygtls::handle_SIGCONT()
>
> wait_sig() is a thread which handle received signals, so other
> threads than wait_sig() thread do not set the current_sig to non-zero.
> That is, other threads set current_sig only to zero. Therefore,
> I think we don't have to guard checking current_sig value by lock.
> The only thing we shoud guard is the following case.
>
> [wait_sig()]               [another thread]
> current_sig = SIGCONT;
>                            current_sig = 0;
> set_signal_arrived();
>
> So, we should place current_sig = SIGCONT and set_signal_arrived()
> inside the lock.
>

OK, that makes sense.

> As for volatile, personally, I have never had any problems by
> not marking variables that are accessed by multiple threads as
> volatile. Do you have any example that causes problem due to
> lack of volatile other than, say, hardware registers?

After I sent that, I realized that it should be fine - yield calls Sleep
which is an external function, and I think the compiler cannot know that
it doesn't modify the variable.

The thing I think volatile protects against is if you didn't do
something that could "clobber memory" in __asm__ speak:

while (sig == SIGCONT)
  __asm__ ("pause":::);

then the compiler could load the value into a register and just check the
register rather than re-loading from memory each time through the loop.
And at that point, just optimize it into an infinite loop.  Either calling
an external function or making sig volatile would fix that.  I was playing
with https://gcc.godbolt.org/z/f49vsecYe you can see the effects of making
mem volatile are the same as having Sleep be a function the compiler
cannot inline.

Reply via email to