# HG changeset patch # User Arun Giridhar # Date 1670082872 18000 # Node ID 06a5dd3c7358c2af40bfb0229e79c85108b915dd # Parent 4c040e1edb4b94bb4062f3deb90d5f5bca0ddfc7# Parent d9970470108ac02d2bbe36996ee072d99c5ab2cd maint: Merge stable to default. diff -r 4c040e1edb4b -r 06a5dd3c7358 libinterp/corefcn/interpreter.cc --- a/libinterp/corefcn/interpreter.cc Sat Dec 03 13:56:11 2022 +0100 +++ b/libinterp/corefcn/interpreter.cc Sat Dec 03 10:54:32 2022 -0500 @@ -91,7 +91,7 @@ bool octave_interpreter_ready = false; // TRUE means we've processed all the init code and we are good to go. -bool octave_initialized = false; +std::atomic octave_initialized{false}; OCTAVE_BEGIN_NAMESPACE(octave) @@ -1950,7 +1950,7 @@ can_interrupt = true; octave_interrupt_state = 0; - octave_signal_caught = 0; + octave_signal_caught = false; octave_restore_signal_mask (); catch_interrupts (); } diff -r 4c040e1edb4b -r 06a5dd3c7358 libinterp/corefcn/interpreter.h --- a/libinterp/corefcn/interpreter.h Sat Dec 03 13:56:11 2022 +0100 +++ b/libinterp/corefcn/interpreter.h Sat Dec 03 10:54:32 2022 -0500 @@ -28,6 +28,7 @@ #include "octave-config.h" +#include #include #include #include @@ -66,7 +67,7 @@ extern OCTINTERP_API bool octave_interpreter_ready; // TRUE means we've processed all the init code and we are good to go. -extern OCTINTERP_API bool octave_initialized; +extern OCTINTERP_API std::atomic octave_initialized; #include "oct-time.h" diff -r 4c040e1edb4b -r 06a5dd3c7358 libinterp/corefcn/sighandlers.cc --- a/libinterp/corefcn/sighandlers.cc Sat Dec 03 13:56:11 2022 +0100 +++ b/libinterp/corefcn/sighandlers.cc Sat Dec 03 10:54:32 2022 -0500 @@ -27,6 +27,7 @@ # include "config.h" #endif +#include #include #include @@ -65,7 +66,7 @@ int pipe_handler_error_count = 0; // TRUE means we can be interrupted. -bool can_interrupt = false; +std::atomic can_interrupt{false}; // TRUE means we should try to enter the debugger on SIGINT. bool Vdebug_on_interrupt = false; @@ -82,7 +83,7 @@ static bool Vsigterm_dumps_octave_core = true; // List of signals we have caught since last call to signal_handler. -static bool *signals_caught = nullptr; +static std::atomic *signals_caught = nullptr; static void my_friendly_exit (int sig, bool save_vars = true) @@ -194,10 +195,10 @@ for (int sig = 0; sig < octave_num_signals (); sig++) { - if (signals_caught[sig]) + bool expected = true; + + if (signals_caught[sig].compare_exchange_strong (expected, false)) { - signals_caught[sig] = false; - if ((have_sigchld && sig == sigchld) || (have_sigcld && sig == sigcld)) { @@ -223,9 +224,22 @@ // FIXME: is this really needed? Does it do anything // useful now? - if (pipe_handler_error_count++ > 100 - && octave_interrupt_state >= 0) - octave_interrupt_state++; + const int curr_pipe_handler_error_count = pipe_handler_error_count++; + + if (curr_pipe_handler_error_count > 100) + { + sig_atomic_t curr_interrupt_state + = octave_interrupt_state.load(); + + sig_atomic_t new_interrupt_state; + + do + new_interrupt_state = curr_interrupt_state + 1; + while (curr_interrupt_state >= 0 && + ! octave_interrupt_state.compare_exchange_weak + (curr_interrupt_state, new_interrupt_state)); + } + } else if (have_sighup && sig == sighup) my_friendly_exit (sighup, Vsighup_dumps_octave_core); @@ -276,7 +290,7 @@ // signal watcher thread so it should probably be more careful about // how it accesses global objects. - octave_signal_caught = 1; + octave_signal_caught = true; signals_caught[sig] = true; @@ -296,7 +310,7 @@ if (can_interrupt) { - octave_signal_caught = 1; + octave_signal_caught = true; octave_interrupt_state++; } } @@ -365,7 +379,7 @@ install_signal_handlers (void) { if (! signals_caught) - signals_caught = new bool [octave_num_signals ()]; + signals_caught = new std::atomic [octave_num_signals ()]; for (int i = 0; i < octave_num_signals (); i++) signals_caught[i] = false; diff -r 4c040e1edb4b -r 06a5dd3c7358 libinterp/corefcn/sighandlers.h --- a/libinterp/corefcn/sighandlers.h Sat Dec 03 13:56:11 2022 +0100 +++ b/libinterp/corefcn/sighandlers.h Sat Dec 03 10:54:32 2022 -0500 @@ -36,6 +36,8 @@ #if ! defined (octave_sighandlers_h) #define octave_sighandlers_h 1 +#include + #include "octave-config.h" #include "child-list.h" @@ -56,7 +58,7 @@ extern int pipe_handler_error_count; // TRUE means we can be interrupted. -extern OCTINTERP_API bool can_interrupt; +extern OCTINTERP_API std::atomic can_interrupt; extern OCTINTERP_API sig_handler * set_signal_handler (int sig, sig_handler *h, diff -r 4c040e1edb4b -r 06a5dd3c7358 liboctave/util/action-container.h --- a/liboctave/util/action-container.h Sat Dec 03 13:56:11 2022 +0100 +++ b/liboctave/util/action-container.h Sat Dec 03 10:54:32 2022 -0500 @@ -28,6 +28,7 @@ #include "octave-config.h" +#include #include #include @@ -39,6 +40,22 @@ OCTAVE_BEGIN_NAMESPACE(octave) +OCTAVE_BEGIN_NAMESPACE(util) + +template +struct atomic_traits +{ + typedef T type; +}; + +template +struct atomic_traits> +{ + typedef T type; +}; + +OCTAVE_END_NAMESPACE(util) + class action_container { @@ -106,7 +123,8 @@ private: - T *m_ptr, m_val; + T *m_ptr; + typename util::atomic_traits::type m_val; }; // Deletes a class allocated using new. diff -r 4c040e1edb4b -r 06a5dd3c7358 liboctave/util/cmd-edit.cc --- a/liboctave/util/cmd-edit.cc Sat Dec 03 13:56:11 2022 +0100 +++ b/liboctave/util/cmd-edit.cc Sat Dec 03 10:54:32 2022 -0500 @@ -785,7 +785,7 @@ void gnu_readline::do_handle_interrupt_signal (void) { - octave_signal_caught = 0; + octave_signal_caught = false; octave_interrupt_state = 0; ::octave_rl_recover_from_interrupt (); diff -r 4c040e1edb4b -r 06a5dd3c7358 liboctave/util/oct-atomic.c --- a/liboctave/util/oct-atomic.c Sat Dec 03 13:56:11 2022 +0100 +++ b/liboctave/util/oct-atomic.c Sat Dec 03 10:54:32 2022 -0500 @@ -29,9 +29,23 @@ #include "oct-atomic.h" +#if defined (__GNUC__) + +octave_idx_type +octave_atomic_increment (octave_idx_type *x) +{ + return __sync_add_and_fetch (x, 1); +} + +octave_idx_type +octave_atomic_decrement (octave_idx_type *x) +{ + return __sync_sub_and_fetch (x, 1); +} + /* Some versions of GCC can't compile stdatomic.h with -fopenmp. */ -#if defined (OCTAVE_STDATOMIC_H_OK) +#elif defined (OCTAVE_STDATOMIC_H_OK) # include octave_idx_type @@ -52,20 +66,6 @@ return *x; } -#elif defined (__GNUC__) - -octave_idx_type -octave_atomic_increment (octave_idx_type *x) -{ - return __sync_add_and_fetch (x, 1); -} - -octave_idx_type -octave_atomic_decrement (octave_idx_type *x) -{ - return __sync_sub_and_fetch (x, 1); -} - #elif defined (_MSC_VER) # include diff -r 4c040e1edb4b -r 06a5dd3c7358 liboctave/util/quit.cc --- a/liboctave/util/quit.cc Sat Dec 03 13:56:11 2022 +0100 +++ b/liboctave/util/quit.cc Sat Dec 03 10:54:32 2022 -0500 @@ -27,6 +27,7 @@ # include "config.h" #endif +#include #include #include @@ -35,9 +36,9 @@ #include "quit.h" -sig_atomic_t octave_interrupt_state = 0; +std::atomic octave_interrupt_state{0}; -volatile sig_atomic_t octave_signal_caught = 0; +volatile std::atomic octave_signal_caught{false}; void (*octave_signal_hook) (void) = nullptr; void (*octave_interrupt_hook) (void) = nullptr; @@ -95,6 +96,11 @@ } } +void octave_quit_c (void) +{ + octave_quit (); +} + OCTAVE_END_NAMESPACE(octave) void @@ -103,10 +109,12 @@ if (octave_signal_hook) octave_signal_hook (); - if (octave_interrupt_state > 0) - { - octave_interrupt_state = -1; + sig_atomic_t curr_interrupt_state = octave_interrupt_state.load (); - throw octave::interrupt_exception (); - } + while (curr_interrupt_state > 0 && + ! octave_interrupt_state.compare_exchange_weak (curr_interrupt_state, -1)) + ; + + if (curr_interrupt_state > 0) + throw octave::interrupt_exception (); } diff -r 4c040e1edb4b -r 06a5dd3c7358 liboctave/util/quit.h --- a/liboctave/util/quit.h Sat Dec 03 13:56:11 2022 +0100 +++ b/liboctave/util/quit.h Sat Dec 03 10:54:32 2022 -0500 @@ -30,6 +30,7 @@ /* The signal header is just needed for the sig_atomic_t type. */ #if defined (__cplusplus) +# include # include # include # include @@ -223,9 +224,14 @@ 0: no interrupt pending < 0: handling interrupt */ -extern OCTAVE_API sig_atomic_t octave_interrupt_state; + +#if defined (__cplusplus) -extern OCTAVE_API volatile sig_atomic_t octave_signal_caught; +extern OCTAVE_API std::atomic octave_interrupt_state; + +extern OCTAVE_API volatile std::atomic octave_signal_caught; + +#endif extern OCTAVE_API void octave_handle_signal (void); @@ -233,27 +239,19 @@ inline void octave_quit (void) { - if (octave_signal_caught) - { - octave_signal_caught = 0; - octave_handle_signal (); - } + bool expected = true; + + if (octave_signal_caught.compare_exchange_strong (expected, false)) + octave_handle_signal (); } #define OCTAVE_QUIT octave_quit () #else -#define OCTAVE_QUIT \ - do \ - { \ - if (octave_signal_caught) \ - { \ - octave_signal_caught = 0; \ - octave_handle_signal (); \ - } \ - } \ - while (0) +extern OCTAVE_API void octave_quit_c (void); +#define OCTAVE_QUIT octave_quit_c () + #endif /* The following macros are obsolete. Interrupting immediately by