summaryrefslogtreecommitdiff
path: root/quantum/split_common
diff options
context:
space:
mode:
authorStefan Kerkmann <karlk90@pm.me>2022-10-04 20:49:29 +0200
committerGitHub <noreply@github.com>2022-10-05 05:49:29 +1100
commit56f7b34289e7f80ac540a7c9c01a5c3a3838cd7c (patch)
tree2e05bad07c94dc4fdbf52d5d85c906d5c55d6b81 /quantum/split_common
parent89e75f6230e4251e1f9f7ba44d6e3720d00204e9 (diff)
[Core] rewrite locking in split transaction handlers (#18417)
Diffstat (limited to 'quantum/split_common')
-rw-r--r--quantum/split_common/transactions.c121
1 files changed, 88 insertions, 33 deletions
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c
index 719068908f..13fd8a761e 100644
--- a/quantum/split_common/transactions.c
+++ b/quantum/split_common/transactions.c
@@ -76,8 +76,27 @@ static bool transaction_handler_master(matrix_row_t master_matrix[], matrix_row_
76 if (!transaction_handler_master(master_matrix, slave_matrix, #prefix, &prefix##_handlers_master)) return false; \ 76 if (!transaction_handler_master(master_matrix, slave_matrix, #prefix, &prefix##_handlers_master)) return false; \
77 } while (0) 77 } while (0)
78 78
79/**
80 * @brief Constructs a transaction handler that doesn't acquire a lock to the
81 * split shared memory. Therefore the locking and unlocking has to be done
82 * manually inside the handler. Use this macro only if the handler is
83 * non-deterministic in runtime and thus needs a manual lock unlock
84 * implementation to hold the lock for the shortest possible time.
85 */
79#define TRANSACTION_HANDLER_SLAVE(prefix) \ 86#define TRANSACTION_HANDLER_SLAVE(prefix) \
80 do { \ 87 do { \
88 prefix##_handlers_slave(master_matrix, slave_matrix); \
89 } while (0)
90
91/**
92 * @brief Constructs a transaction handler that automatically acquires a lock to
93 * safely access the split shared memory and releases the lock again after
94 * processing the handler. Use this macro if the handler is fast and
95 * deterministic in runtime and thus holds the lock only for a very short time.
96 * If not fallback to manually locking and unlocking inside the handler.
97 */
98#define TRANSACTION_HANDLER_SLAVE_AUTOLOCK(prefix) \
99 do { \
81 split_shared_memory_lock(); \ 100 split_shared_memory_lock(); \
82 prefix##_handlers_slave(master_matrix, slave_matrix); \ 101 prefix##_handlers_slave(master_matrix, slave_matrix); \
83 split_shared_memory_unlock(); \ 102 split_shared_memory_unlock(); \
@@ -139,7 +158,7 @@ static void slave_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row
139 158
140// clang-format off 159// clang-format off
141#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix) 160#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix)
142#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix) 161#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(slave_matrix)
143#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \ 162#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \
144 [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \ 163 [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \
145 [GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix), 164 [GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix),
@@ -161,7 +180,7 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro
161} 180}
162 181
163# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix) 182# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix)
164# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix) 183# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(master_matrix)
165# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), 184# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix),
166 185
167#else // SPLIT_TRANSPORT_MIRROR 186#else // SPLIT_TRANSPORT_MIRROR
@@ -197,7 +216,7 @@ static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sl
197 216
198// clang-format off 217// clang-format off
199# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder) 218# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder)
200# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder) 219# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(encoder)
201# define TRANSACTIONS_ENCODERS_REGISTRATIONS \ 220# define TRANSACTIONS_ENCODERS_REGISTRATIONS \
202 [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ 221 [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \
203 [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state), 222 [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state),
@@ -239,7 +258,7 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
239} 258}
240 259
241# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer) 260# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer)
242# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer) 261# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(sync_timer)
243# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), 262# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer),
244 263
245#else // DISABLE_SYNC_TIMER 264#else // DISABLE_SYNC_TIMER
@@ -273,7 +292,7 @@ static void layer_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_
273 292
274// clang-format off 293// clang-format off
275# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state) 294# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state)
276# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state) 295# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(layer_state)
277# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \ 296# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \
278 [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \ 297 [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \
279 [PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state), 298 [PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state),
@@ -304,7 +323,7 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
304} 323}
305 324
306# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state) 325# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state)
307# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state) 326# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(led_state)
308# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), 327# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state),
309 328
310#else // SPLIT_LED_STATE_ENABLE 329#else // SPLIT_LED_STATE_ENABLE
@@ -353,10 +372,15 @@ static bool mods_handlers_master(matrix_row_t master_matrix[], matrix_row_t slav
353} 372}
354 373
355static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 374static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
356 set_mods(split_shmem->mods.real_mods); 375 split_shared_memory_lock();
357 set_weak_mods(split_shmem->mods.weak_mods); 376 split_mods_sync_t mods;
377 memcpy(&mods, &split_shmem->mods, sizeof(split_mods_sync_t));
378 split_shared_memory_unlock();
379
380 set_mods(mods.real_mods);
381 set_weak_mods(mods.weak_mods);
358# ifndef NO_ACTION_ONESHOT 382# ifndef NO_ACTION_ONESHOT
359 set_oneshot_mods(split_shmem->mods.oneshot_mods); 383 set_oneshot_mods(mods.oneshot_mods);
360# endif 384# endif
361} 385}
362 386
@@ -384,7 +408,11 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t
384} 408}
385 409
386static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 410static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
387 backlight_set(split_shmem->backlight_level); 411 split_shared_memory_lock();
412 uint8_t backlight_level = split_shmem->backlight_level;
413 split_shared_memory_unlock();
414
415 backlight_set(backlight_level);
388} 416}
389 417
390# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight) 418# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight)
@@ -417,10 +445,15 @@ static bool rgblight_handlers_master(matrix_row_t master_matrix[], matrix_row_t
417} 445}
418 446
419static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 447static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
448 split_shared_memory_lock();
420 // Update the RGB with the new data 449 // Update the RGB with the new data
421 if (split_shmem->rgblight_sync.status.change_flags != 0) { 450 rgblight_syncinfo_t rgblight_sync;
422 rgblight_update_sync(&split_shmem->rgblight_sync, false); 451 memcpy(&rgblight_sync, &split_shmem->rgblight_sync, sizeof(rgblight_syncinfo_t));
423 split_shmem->rgblight_sync.status.change_flags = 0; 452 split_shmem->rgblight_sync.status.change_flags = 0;
453 split_shared_memory_unlock();
454
455 if (rgblight_sync.status.change_flags != 0) {
456 rgblight_update_sync(&rgblight_sync, false);
424 } 457 }
425} 458}
426 459
@@ -450,8 +483,12 @@ static bool led_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_
450} 483}
451 484
452static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 485static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
486 split_shared_memory_lock();
453 memcpy(&led_matrix_eeconfig, &split_shmem->led_matrix_sync.led_matrix, sizeof(led_eeconfig_t)); 487 memcpy(&led_matrix_eeconfig, &split_shmem->led_matrix_sync.led_matrix, sizeof(led_eeconfig_t));
454 led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state); 488 bool led_suspend_state = split_shmem->led_matrix_sync.led_suspend_state;
489 split_shared_memory_unlock();
490
491 led_matrix_set_suspend_state(led_suspend_state);
455} 492}
456 493
457# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix) 494# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix)
@@ -480,8 +517,12 @@ static bool rgb_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_
480} 517}
481 518
482static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 519static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
520 split_shared_memory_lock();
483 memcpy(&rgb_matrix_config, &split_shmem->rgb_matrix_sync.rgb_matrix, sizeof(rgb_config_t)); 521 memcpy(&rgb_matrix_config, &split_shmem->rgb_matrix_sync.rgb_matrix, sizeof(rgb_config_t));
484 rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state); 522 bool rgb_suspend_state = split_shmem->rgb_matrix_sync.rgb_suspend_state;
523 split_shared_memory_unlock();
524
525 rgb_matrix_set_suspend_state(rgb_suspend_state);
485} 526}
486 527
487# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix) 528# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix)
@@ -512,7 +553,7 @@ static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_
512} 553}
513 554
514# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm) 555# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm)
515# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm) 556# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(wpm)
516# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), 557# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm),
517 558
518#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) 559#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)
@@ -535,7 +576,11 @@ static bool oled_handlers_master(matrix_row_t master_matrix[], matrix_row_t slav
535} 576}
536 577
537static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 578static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
538 if (split_shmem->current_oled_state) { 579 split_shared_memory_lock();
580 uint8_t current_oled_state = split_shmem->current_oled_state;
581 split_shared_memory_unlock();
582
583 if (current_oled_state) {
539 oled_on(); 584 oled_on();
540 } else { 585 } else {
541 oled_off(); 586 oled_off();
@@ -566,7 +611,11 @@ static bool st7565_handlers_master(matrix_row_t master_matrix[], matrix_row_t sl
566} 611}
567 612
568static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { 613static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
569 if (split_shmem->current_st7565_state) { 614 split_shared_memory_lock();
615 uint8_t current_st7565_state = split_shmem->current_st7565_state;
616 split_shared_memory_unlock();
617
618 if (current_st7565_state) {
570 st7565_on(); 619 st7565_on();
571 } else { 620 } else {
572 st7565_off(); 621 st7565_off();
@@ -574,7 +623,7 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla
574} 623}
575 624
576# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565) 625# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565)
577# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565) 626# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(st7565)
578# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state), 627# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state),
579 628
580#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) 629#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)
@@ -607,9 +656,9 @@ static bool pointing_handlers_master(matrix_row_t master_matrix[], matrix_row_t
607 bool okay = read_if_checksum_mismatch(GET_POINTING_CHECKSUM, GET_POINTING_DATA, &last_update, &temp_state, &split_shmem->pointing.report, sizeof(temp_state)); 656 bool okay = read_if_checksum_mismatch(GET_POINTING_CHECKSUM, GET_POINTING_DATA, &last_update, &temp_state, &split_shmem->pointing.report, sizeof(temp_state));
608 if (okay) pointing_device_set_shared_report(temp_state); 657 if (okay) pointing_device_set_shared_report(temp_state);
609 temp_cpi = pointing_device_get_shared_cpi(); 658 temp_cpi = pointing_device_get_shared_cpi();
610 if (temp_cpi && memcmp(&last_cpi, &temp_cpi, sizeof(temp_cpi)) != 0) { 659 if (temp_cpi && last_cpi != temp_cpi) {
611 memcpy(&split_shmem->pointing.cpi, &temp_cpi, sizeof(temp_cpi)); 660 split_shmem->pointing.cpi = temp_cpi;
612 okay = transport_write(PUT_POINTING_CPI, &split_shmem->pointing.cpi, sizeof(split_shmem->pointing.cpi)); 661 okay = transport_write(PUT_POINTING_CPI, &split_shmem->pointing.cpi, sizeof(split_shmem->pointing.cpi));
613 if (okay) { 662 if (okay) {
614 last_cpi = temp_cpi; 663 last_cpi = temp_cpi;
615 } 664 }
@@ -629,8 +678,6 @@ static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
629 return; 678 return;
630 } 679 }
631# endif 680# endif
632 report_mouse_t temp_report;
633 uint16_t temp_cpi;
634# if (POINTING_DEVICE_TASK_THROTTLE_MS > 0) 681# if (POINTING_DEVICE_TASK_THROTTLE_MS > 0)
635 static uint32_t last_exec = 0; 682 static uint32_t last_exec = 0;
636 if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) { 683 if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) {
@@ -638,17 +685,25 @@ static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
638 } 685 }
639 last_exec = timer_read32(); 686 last_exec = timer_read32();
640# endif 687# endif
641 temp_cpi = !pointing_device_driver.get_cpi ? 0 : pointing_device_driver.get_cpi(); // check for NULL 688
642 if (split_shmem->pointing.cpi && memcmp(&split_shmem->pointing.cpi, &temp_cpi, sizeof(temp_cpi)) != 0) { 689 uint16_t temp_cpi = !pointing_device_driver.get_cpi ? 0 : pointing_device_driver.get_cpi(); // check for NULL
643 if (pointing_device_driver.set_cpi) { 690
644 pointing_device_driver.set_cpi(split_shmem->pointing.cpi); 691 split_shared_memory_lock();
645 } 692 split_slave_pointing_sync_t pointing;
693 memcpy(&pointing, &split_shmem->pointing, sizeof(split_slave_pointing_sync_t));
694 split_shared_memory_unlock();
695
696 if (pointing.cpi && pointing.cpi != temp_cpi && pointing_device_driver.set_cpi) {
697 pointing_device_driver.set_cpi(pointing.cpi);
646 } 698 }
647 memset(&temp_report, 0, sizeof(temp_report)); 699
648 temp_report = pointing_device_driver.get_report(temp_report); 700 pointing.report = pointing_device_driver.get_report((report_mouse_t){0});
649 memcpy(&split_shmem->pointing.report, &temp_report, sizeof(temp_report));
650 // Now update the checksum given that the pointing has been written to 701 // Now update the checksum given that the pointing has been written to
651 split_shmem->pointing.checksum = crc8(&temp_report, sizeof(temp_report)); 702 pointing.checksum = crc8(&pointing.report, sizeof(report_mouse_t));
703
704 split_shared_memory_lock();
705 memcpy(&split_shmem->pointing, &pointing, sizeof(split_slave_pointing_sync_t));
706 split_shared_memory_unlock();
652} 707}
653 708
654# define TRANSACTIONS_POINTING_MASTER() TRANSACTION_HANDLER_MASTER(pointing) 709# define TRANSACTIONS_POINTING_MASTER() TRANSACTION_HANDLER_MASTER(pointing)