On Sat, 18 Jan 2025 19:24:51 -0800 (PST) Jeremy Drake <cyg...@jdrake.com> wrote:
> 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. Ah, I was wrong. Following code needs volatile for "int a" as you pointed out. #include <pthread.h> int a = 0; void *func(void *arg) { a = 1; return NULL; } int main() { pthread_t th; pthread_create(&th, NULL, func, NULL); while (a == 0) ; pthread_join(th, NULL); return 0; } -- Takashi Yano <takashi.y...@nifty.ne.jp>