From 5594268869809d7cd7d4ee85199a88894aa1e49b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20F=2E=20Wittenberger?=
<Joerg.Wittenberger@softeyes.net>
Date: Thu, 3 Dec 2015 10:52:06 +0100
Subject: [PATCH] Allow signal handlers to be dispatched to multiple threads.
---
runtime.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/runtime.c b/runtime.c
index 9d93476..78d098f 100644
a
|
b
|
C_regparm void C_fcall C_paranoid_check_for_interrupt(void) |
4394 | 4394 | |
4395 | 4395 | C_regparm void C_fcall C_raise_interrupt(int reason) |
4396 | 4396 | { |
| 4397 | /* If signals are dispatched to several threads in parallel more |
| 4398 | than one may take this code path. Make sure that at least no |
| 4399 | thread will write a value to saved_stack_limit which was obtained |
| 4400 | from C_stack_limit at a time when pending_interrupts_count was |
| 4401 | not zero (and thus C_stack_limit possibly already updated from |
| 4402 | the other thread). We 1. remember C_stack_limit, 2. test |
| 4403 | pending_interrupts_count==0, 3. set pending_interrupts_count, |
| 4404 | 4. write _the remembered_ value to saved_stack_limit. */ |
| 4405 | C_word *stack_limit = C_stack_limit; // remember this first |
4397 | 4406 | if(C_interrupts_enabled) { |
4398 | 4407 | if(pending_interrupts_count == 0 && !handling_interrupts) { |
4399 | | /* Force the next stack check to fail by faking a "full" stack. |
4400 | | That causes save_and_reclaim() to be called, which will |
4401 | | invoke handle_interrupt() (which restores the stack limit). */ |
4402 | | saved_stack_limit = C_stack_limit; |
4403 | | |
4404 | | #if C_STACK_GROWS_DOWNWARD |
4405 | | C_stack_limit = C_stack_pointer + 1000; |
4406 | | #else |
4407 | | C_stack_limit = C_stack_pointer - 1000; |
4408 | | #endif |
4409 | | interrupt_time = C_cpu_milliseconds(); |
4410 | 4408 | pending_interrupts[ pending_interrupts_count++ ] = reason; |
| 4409 | /* Force the next stack check |
| 4410 | to fail by faking a "full" stack. That causes |
| 4411 | save_and_reclaim() to be called, which will invoke |
| 4412 | handle_interrupt() (which restores the stack limit). */ |
| 4413 | saved_stack_limit = stack_limit; /* first write the backup going to be restored */ |
| 4414 | C_stack_limit = stack_bottom; /* then fake the full stack */ |
| 4415 | interrupt_time = C_cpu_milliseconds(); |
4411 | 4416 | } else if(pending_interrupts_count < MAX_PENDING_INTERRUPTS) { |
4412 | 4417 | int i; |
4413 | 4418 | /* |