Skip to content

Commit 190f427

Browse files
committed
Use a RAII approach for linux signal blocking
1 parent 0204c25 commit 190f427

File tree

4 files changed

+116
-148
lines changed

4 files changed

+116
-148
lines changed

include/acl_thread.h

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,13 @@ static inline void acl_sig_finished() {
6767
}
6868

6969
// Blocking/Unblocking signals (Only implemented for Linux)
70-
#ifdef __linux__
71-
extern ACL_TLS sigset_t acl_sigset;
72-
static inline void acl_sig_block_signals() {
73-
sigset_t mask;
74-
if (sigfillset(&mask))
75-
assert(0 && "Error in creating signal mask in status handler");
76-
if (pthread_sigmask(SIG_BLOCK, &mask, &acl_sigset))
77-
assert(0 && "Error in blocking signals in status handler");
78-
}
79-
static inline void acl_sig_unblock_signals() {
80-
if (pthread_sigmask(SIG_SETMASK, &acl_sigset, NULL))
81-
assert(0 && "Error in unblocking signals in status handler");
82-
}
83-
#endif
70+
class acl_signal_blocker {
71+
public:
72+
acl_signal_blocker &operator=(const acl_signal_blocker &) = delete;
73+
acl_signal_blocker(const acl_signal_blocker &) = delete;
74+
acl_signal_blocker();
75+
~acl_signal_blocker();
76+
};
8477

8578
// -- global lock functions --
8679

src/acl_hal_mmd.cpp

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,13 +1985,13 @@ int acl_hal_mmd_program_device(unsigned int physical_device_id,
19851985

19861986
void acl_hal_mmd_kernel_interrupt(int handle_in, void *user_data) {
19871987
unsigned physical_device_id;
1988-
#ifdef __linux__
1988+
19891989
// Callbacks received from non-dma transfers.
19901990
// (those calls are not initiated by a signal handler, so we need to block all
19911991
// signals here to avoid simultaneous calls to signal handler.)
1992-
acl_sig_block_signals(); // Call before acl_sig_started. Must call
1993-
// acl_sig_unblock_signals after acl_sig_finished.
1994-
#endif
1992+
// Must instantiate before acl_sig_started, destruct after acl_sig_finished.
1993+
acl_signal_blocker sig_blocker;
1994+
19951995
acl_sig_started();
19961996
// NOTE: all exit points of this function must first call acl_sig_finished()
19971997

@@ -2005,10 +2005,6 @@ void acl_hal_mmd_kernel_interrupt(int handle_in, void *user_data) {
20052005
assert(acl_kernel_if_is_valid(&kern[physical_device_id]));
20062006
acl_kernel_if_update_status(&kern[physical_device_id]);
20072007
acl_sig_finished();
2008-
#ifdef __linux__
2009-
// Unblocking the signals we blocked
2010-
acl_sig_unblock_signals();
2011-
#endif
20122008
return;
20132009
}
20142010

@@ -2021,14 +2017,13 @@ void acl_hal_mmd_device_interrupt(int handle_in,
20212017
aocl_mmd_interrupt_info *data_in,
20222018
void *user_data) {
20232019
unsigned physical_device_id;
2024-
#ifdef __linux__
2020+
20252021
// Callbacks received from non-dma transfers.
2026-
//(those calls are not initiated by a signal handler, so we need to block all
2027-
// signals
2028-
// here to avoid simultaneous calls to signal handler.)
2029-
acl_sig_block_signals(); // Call before acl_sig_started. Must call
2030-
// acl_sig_unblock_signals after acl_sig_finished.
2031-
#endif
2022+
// (those calls are not initiated by a signal handler, so we need to block all
2023+
// signals here to avoid simultaneous calls to signal handler.)
2024+
// Must instantiate before acl_sig_started, destruct after acl_sig_finished.
2025+
acl_signal_blocker sig_blocker;
2026+
20322027
acl_sig_started();
20332028
// NOTE: all exit points of this function must first call acl_sig_finished()
20342029

@@ -2042,10 +2037,6 @@ void acl_hal_mmd_device_interrupt(int handle_in,
20422037
acl_device_update_fn(physical_device_id, data_in->exception_type,
20432038
data_in->user_private_info, data_in->user_cb);
20442039
acl_sig_finished();
2045-
#ifdef __linux__
2046-
// Unblocking the signals we blocked
2047-
acl_sig_unblock_signals();
2048-
#endif
20492040
return;
20502041
}
20512042

@@ -2056,14 +2047,12 @@ void acl_hal_mmd_device_interrupt(int handle_in,
20562047

20572048
void acl_hal_mmd_status_handler(int handle, void *user_data, aocl_mmd_op_t op,
20582049
int status) {
2059-
#ifdef __linux__
20602050
// Callbacks received from non-dma transfers.
2061-
//(those calls are not initiated by a signal handler, so we need to block all
2062-
// signals)
2063-
// here to avoid simultaneous calls to signal handler.)
2064-
acl_sig_block_signals(); // Call before acl_sig_started. Must call
2065-
// acl_sig_unblock_signals after acl_sig_finished.
2066-
#endif
2051+
// (those calls are not initiated by a signal handler, so we need to block all
2052+
// signals here to avoid simultaneous calls to signal handler.)
2053+
// Must instantiate before acl_sig_started, destruct after acl_sig_finished.
2054+
acl_signal_blocker sig_blocker;
2055+
20672056
acl_sig_started();
20682057
// NOTE: all exit points of this function must first call acl_sig_finished()
20692058
// Removing Windows warning
@@ -2073,10 +2062,6 @@ void acl_hal_mmd_status_handler(int handle, void *user_data, aocl_mmd_op_t op,
20732062
acl_event_update_fn((cl_event)op, CL_COMPLETE);
20742063

20752064
acl_sig_finished();
2076-
#ifdef __linux__
2077-
// Unblocking the signals we blocked
2078-
acl_sig_unblock_signals();
2079-
#endif
20802065
}
20812066

20822067
void acl_hal_mmd_register_callbacks(

src/acl_kernel_if.cpp

Lines changed: 73 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -400,42 +400,30 @@ static uintptr_t acl_kernel_cra_set_segment_rom(acl_kernel_if *kern,
400400

401401
static int acl_kernel_cra_read(acl_kernel_if *kern, unsigned int accel_id,
402402
unsigned int addr, unsigned int *val) {
403-
int result = 0;
404403
assert(kern->cra_ring_root_exist);
405-
#ifdef __linux__
406-
acl_sig_block_signals();
407-
#endif
408-
{
409-
std::lock_guard<std::mutex> lock(kern->segment_mutex);
410-
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
411-
acl_assert_locked_or_sig();
412-
result = acl_kernel_if_read_32b(
413-
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
414-
}
415-
#ifdef __linux__
416-
acl_sig_unblock_signals();
417-
#endif
418-
return result;
404+
405+
// Need to block signals before acquiring mutex and unblock after releasing
406+
acl_signal_blocker sig_blocker;
407+
std::lock_guard<std::mutex> lock(kern->segment_mutex);
408+
409+
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
410+
acl_assert_locked_or_sig();
411+
return acl_kernel_if_read_32b(
412+
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
419413
}
420414

421415
int acl_kernel_cra_read_64b(acl_kernel_if *kern, unsigned int accel_id,
422416
unsigned int addr, uint64_t *val) {
423-
int result = 0;
424417
assert(kern->cra_ring_root_exist);
425-
#ifdef __linux__
426-
acl_sig_block_signals();
427-
#endif
428-
{
429-
std::lock_guard<std::mutex> lock(kern->segment_mutex);
430-
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
431-
acl_assert_locked_or_sig();
432-
result = acl_kernel_if_read_64b(
433-
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
434-
}
435-
#ifdef __linux__
436-
acl_sig_unblock_signals();
437-
#endif
438-
return result;
418+
419+
// Need to block signals before acquiring mutex and unblock after releasing
420+
acl_signal_blocker sig_blocker;
421+
std::lock_guard<std::mutex> lock(kern->segment_mutex);
422+
423+
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
424+
acl_assert_locked_or_sig();
425+
return acl_kernel_if_read_64b(
426+
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
439427
}
440428

441429
// Read 32b from kernel ROM
@@ -483,95 +471,76 @@ static int acl_kernel_rom_cra_read_block(acl_kernel_if *kern, unsigned int addr,
483471

484472
static int acl_kernel_cra_write(acl_kernel_if *kern, unsigned int accel_id,
485473
unsigned int addr, unsigned int val) {
486-
int result = 0;
487474
assert(kern->cra_ring_root_exist);
488-
#ifdef __linux__
489-
acl_sig_block_signals();
490-
#endif
491-
{
492-
std::lock_guard<std::mutex> lock(kern->segment_mutex);
493-
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
494-
acl_assert_locked_or_sig();
495-
result = acl_kernel_if_write_32b(
496-
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
497-
}
498-
#ifdef __linux__
499-
acl_sig_unblock_signals();
500-
#endif
501-
return result;
475+
476+
// Need to block signals before acquiring mutex and unblock after releasing
477+
acl_signal_blocker sig_blocker;
478+
std::lock_guard<std::mutex> lock(kern->segment_mutex);
479+
480+
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
481+
acl_assert_locked_or_sig();
482+
return acl_kernel_if_write_32b(
483+
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
502484
}
503485

504486
static int acl_kernel_cra_write_64b(acl_kernel_if *kern, unsigned int accel_id,
505487
unsigned int addr, uint64_t val) {
506-
int result = 0;
507488
assert(kern->cra_ring_root_exist);
508-
#ifdef __linux__
509-
acl_sig_block_signals();
510-
#endif
511-
{
512-
std::lock_guard<std::mutex> lock(kern->segment_mutex);
513-
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
514-
acl_assert_locked();
515-
result = acl_kernel_if_write_64b(
516-
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
517-
}
518-
#ifdef __linux__
519-
acl_sig_unblock_signals();
520-
#endif
521-
return result;
489+
490+
// Need to block signals before acquiring mutex and unblock after releasing
491+
acl_signal_blocker sig_blocker;
492+
std::lock_guard<std::mutex> lock(kern->segment_mutex);
493+
494+
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
495+
acl_assert_locked();
496+
return acl_kernel_if_write_64b(
497+
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val);
522498
}
523499

524500
static int acl_kernel_cra_write_block(acl_kernel_if *kern,
525501
unsigned int accel_id, unsigned int addr,
526502
unsigned int *val, size_t size) {
527-
int result = 0;
528503
assert(kern->cra_ring_root_exist);
529-
#ifdef __linux__
530-
acl_sig_block_signals();
531-
#endif
532-
{
533-
std::lock_guard<std::mutex> lock(kern->segment_mutex);
534-
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
535-
uintptr_t logical_addr =
536-
kern->accel_csr[accel_id].address + addr - OFFSET_KERNEL_CRA;
537-
uintptr_t segment = logical_addr & ((size_t)0 - (KERNEL_CRA_SEGMENT_SIZE));
538-
539-
uintptr_t logical_addr_end =
540-
kern->accel_csr[accel_id].address + addr + size - OFFSET_KERNEL_CRA;
541-
uintptr_t segment_end =
542-
logical_addr_end & ((size_t)0 - (KERNEL_CRA_SEGMENT_SIZE));
543-
544-
unsigned int step = 0;
545-
if (segment != segment_end) {
546-
ACL_KERNEL_IF_DEBUG_MSG_VERBOSE(
547-
kern, 2, ":: Segment change during block write detected.\n");
548-
while (step < size) {
549-
segment =
550-
(logical_addr + step) & ((size_t)0 - (KERNEL_CRA_SEGMENT_SIZE));
551-
if (kern->cur_segment != segment) {
552-
acl_kernel_if_write_block(
553-
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val,
554-
step);
555-
segment_offset =
556-
acl_kernel_cra_set_segment(kern, accel_id, addr + step);
557-
logical_addr = kern->accel_csr[accel_id].address + addr + step -
558-
OFFSET_KERNEL_CRA;
559-
val += step;
560-
size -= step;
561-
step = 0;
562-
} else {
563-
step += (unsigned)sizeof(int);
564-
}
504+
505+
// Need to block signals before acquiring mutex and unblock after releasing
506+
acl_signal_blocker sig_blocker;
507+
std::lock_guard<std::mutex> lock(kern->segment_mutex);
508+
509+
uintptr_t segment_offset = acl_kernel_cra_set_segment(kern, accel_id, addr);
510+
uintptr_t logical_addr =
511+
kern->accel_csr[accel_id].address + addr - OFFSET_KERNEL_CRA;
512+
uintptr_t segment = logical_addr & ((size_t)0 - (KERNEL_CRA_SEGMENT_SIZE));
513+
514+
uintptr_t logical_addr_end =
515+
kern->accel_csr[accel_id].address + addr + size - OFFSET_KERNEL_CRA;
516+
uintptr_t segment_end =
517+
logical_addr_end & ((size_t)0 - (KERNEL_CRA_SEGMENT_SIZE));
518+
519+
unsigned int step = 0;
520+
if (segment != segment_end) {
521+
ACL_KERNEL_IF_DEBUG_MSG_VERBOSE(
522+
kern, 2, ":: Segment change during block write detected.\n");
523+
while (step < size) {
524+
segment = (logical_addr + step) & ((size_t)0 - (KERNEL_CRA_SEGMENT_SIZE));
525+
if (kern->cur_segment != segment) {
526+
acl_kernel_if_write_block(
527+
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val,
528+
step);
529+
segment_offset =
530+
acl_kernel_cra_set_segment(kern, accel_id, addr + step);
531+
logical_addr =
532+
kern->accel_csr[accel_id].address + addr + step - OFFSET_KERNEL_CRA;
533+
val += step;
534+
size -= step;
535+
step = 0;
536+
} else {
537+
step += (unsigned)sizeof(int);
565538
}
566539
}
567-
result = acl_kernel_if_write_block(
568-
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val,
569-
size);
570540
}
571-
#ifdef __linux__
572-
acl_sig_unblock_signals();
573-
#endif
574-
return result;
541+
542+
return acl_kernel_if_write_block(
543+
kern, (unsigned)OFFSET_KERNEL_CRA + (unsigned)segment_offset, val, size);
575544
}
576545

577546
// Private utility function to issue a command to the profile hardware

src/acl_thread.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,27 @@ static void l_init_once() {
135135

136136
#endif // !LINUX
137137

138+
// Blocking/Unblocking signals (Actual implementation only for Linux)
139+
acl_signal_blocker::acl_signal_blocker() {
140+
#ifdef __linux__
141+
sigset_t mask;
142+
if (sigfillset(&mask)) {
143+
assert(0 && "Error in creating signal mask in status handler");
144+
}
145+
if (pthread_sigmask(SIG_BLOCK, &mask, &acl_sigset)) {
146+
assert(0 && "Error in blocking signals in status handler");
147+
}
148+
#endif
149+
}
150+
151+
acl_signal_blocker::~acl_signal_blocker() {
152+
#ifdef __linux__
153+
if (pthread_sigmask(SIG_SETMASK, &acl_sigset, NULL)) {
154+
assert(0 && "Error in unblocking signals in status handler");
155+
}
156+
#endif
157+
}
158+
138159
// Current thread releases mutex lock and sleeps briefly to allow other threads
139160
// a chance to execute. This function is useful for multithreaded hosts with
140161
// e.g. polling BSPs (using yield) to prevent one thread from hogging the mutex

0 commit comments

Comments
 (0)