From 43dfa868929166a768e18902a07f9e5a6a147378 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Mon, 6 May 2024 10:10:55 +0200 Subject: [PATCH 01/51] add benchmark time for flush and new write_n bytes --- include/highlevel/bidib_highlevel_util.h | 3 ++- src/highlevel/bidib_highlevel_util.c | 5 ++++- src/transmission/bidib_transmission_intern.h | 8 ++++++++ src/transmission/bidib_transmission_send.c | 11 +++++++++++ src/transmission/bidib_transmission_serial_port.c | 8 +++++++- .../bidib_transmission_serial_port_intern.h | 8 ++++++++ test/unit/bidib_feedback_tests.c | 11 ++++++++++- test/unit/bidib_highlevel_message_tests.c | 11 ++++++++++- test/unit/bidib_lowlevel_message_tests.c | 11 ++++++++++- test/unit/bidib_parallel_tests.c | 11 ++++++++++- test/unit/bidib_receive_tests.c | 6 +++++- test/unit/bidib_send_tests.c | 11 ++++++++++- test/unit/bidib_state_tests.c | 12 +++++++++++- 13 files changed, 106 insertions(+), 10 deletions(-) diff --git a/include/highlevel/bidib_highlevel_util.h b/include/highlevel/bidib_highlevel_util.h index da3e58c..ef1e1b8 100644 --- a/include/highlevel/bidib_highlevel_util.h +++ b/include/highlevel/bidib_highlevel_util.h @@ -51,7 +51,8 @@ * @return 0 if configs are valid, otherwise 1. */ int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), - const char *config_dir, unsigned int flush_interval); + void (*write_n)(uint8_t*, int32_t), const char *config_dir, + unsigned int flush_interval); /** * Starts the system, handles the connection via a serial port. Also configures diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 9fc04b0..c2eeee9 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -98,7 +98,8 @@ static void bidib_init_threads(unsigned int flush_interval) { } int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), - const char *config_dir, unsigned int flush_interval) { + void (*write_n)(uint8_t*, int32_t), const char *config_dir, + unsigned int flush_interval) { if (read == NULL || write == NULL || (!bidib_lowlevel_debug_mode && config_dir == NULL)) { return 1; } @@ -121,6 +122,7 @@ int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), bidib_set_read_src(read); bidib_set_write_dest(write); + bidib_set_write_n_dest(write_n); bidib_init_threads(flush_interval); @@ -160,6 +162,7 @@ int bidib_start_serial(const char *device, const char *config_dir, unsigned int } else { bidib_set_read_src(bidib_serial_port_read); bidib_set_write_dest(bidib_serial_port_write); + bidib_set_write_n_dest(bidib_serial_port_write_n); bidib_init_threads(flush_interval); diff --git a/src/transmission/bidib_transmission_intern.h b/src/transmission/bidib_transmission_intern.h index 63c5391..f78aba7 100644 --- a/src/transmission/bidib_transmission_intern.h +++ b/src/transmission/bidib_transmission_intern.h @@ -236,6 +236,14 @@ void bidib_set_read_src(uint8_t (*read)(int *)); */ void bidib_set_write_dest(void (*write)(uint8_t)); +/** + * Sets the output of libbidib. + * + * @param write_n a pointer to a function, which sends multiple bytes to the connected + * BiDiB interface. + */ +void bidib_set_write_n_dest(void (*write_n)(uint8_t*, int32_t)); + /** * Sets the maximum capacity for a packet. Default is 64. Max is 256. * diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index a0af7c0..4e41254 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -43,6 +43,7 @@ pthread_mutex_t bidib_send_buffer_mutex; static void (*write_byte)(uint8_t); +static void (*write_bytes)(uint8_t*, int32_t); volatile bool bidib_seq_num_enabled = true; static volatile unsigned int pkt_max_cap = 64; @@ -55,6 +56,11 @@ void bidib_set_write_dest(void (*write)(uint8_t)) { syslog_libbidib(LOG_INFO, "%s", "Write function was set"); } +void bidib_set_write_n_dest(void (*write_n)(uint8_t*, int32_t)) { + write_bytes = write_n; + syslog_libbidib(LOG_INFO, "%s", "Write_n function was set"); +} + void bidib_state_packet_capacity(uint8_t max_capacity) { pthread_mutex_lock(&bidib_send_buffer_mutex); if (max_capacity <= 64) { @@ -99,9 +105,14 @@ static void bidib_flush_impl(void) { } void bidib_flush(void) { + struct timespec start, end; pthread_mutex_lock(&bidib_send_buffer_mutex); + clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_flush_impl(); + clock_gettime(CLOCK_MONOTONIC_RAW, &end); pthread_mutex_unlock(&bidib_send_buffer_mutex); + uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + syslog_libbidib(LOG_WARNING, "Flush took %llu us\n", delta_us); } void *bidib_auto_flush(void *interval) { diff --git a/src/transmission/bidib_transmission_serial_port.c b/src/transmission/bidib_transmission_serial_port.c index f5b33da..1816253 100644 --- a/src/transmission/bidib_transmission_serial_port.c +++ b/src/transmission/bidib_transmission_serial_port.c @@ -120,7 +120,13 @@ uint8_t bidib_serial_port_read(int *byte_read) { void bidib_serial_port_write(uint8_t msg) { if (write(fd, &msg, 1) != 1) { - syslog_libbidib(LOG_ERR, "%s", "Error while sending data via serial port"); + syslog_libbidib(LOG_ERR, "%s", "Error while sending data via serial port (single byte write)"); + } +} + +void bidib_serial_port_write_n(uint8_t *msg, int32_t len) { + if (msg == NULL || len <= 0 || (write(fd, msg, len) != len)) { + syslog_libbidib(LOG_ERR, "Error while sending data via serial port (multi byte write)"); } } diff --git a/src/transmission/bidib_transmission_serial_port_intern.h b/src/transmission/bidib_transmission_serial_port_intern.h index 580f61b..fb0c25c 100644 --- a/src/transmission/bidib_transmission_serial_port_intern.h +++ b/src/transmission/bidib_transmission_serial_port_intern.h @@ -55,6 +55,14 @@ int bidib_detect_baudrate(void); */ void bidib_serial_port_write(uint8_t msg); +/** + * Sends multiple bytes via the serial port to the BiDiB interface. + * + * @param msg the start address of bytes + * @param len the number of bytes to send (msg[0]...msg[len-1]). + */ +void bidib_serial_port_write_n(uint8_t *msg, int32_t len); + /** * Reads a byte from the serial port where the BiDiB interface is connected to. * The method blocks until a message is received. diff --git a/test/unit/bidib_feedback_tests.c b/test/unit/bidib_feedback_tests.c index ca42b33..0d97d4a 100644 --- a/test/unit/bidib_feedback_tests.c +++ b/test/unit/bidib_feedback_tests.c @@ -70,6 +70,15 @@ static void write_byte(uint8_t byte) { output_buffer[output_index++] = byte; } +static void write_bytes(uint8_t* msg, int32_t len) { + if (msg != NULL && len > 0) { + for (int32_t i = 0; i < len; ++i) { + output_buffer[output_index] = msg[i]; + output_index++; + } + } +} + static void test_setup(void) { // response for protocol initialization input_buffer[0] = BIDIB_PKT_MAGIC; @@ -517,7 +526,7 @@ static void feedback_reverser_state(void **state __attribute__((unused))) { int main(void) { test_setup(); - bidib_start_pointer(&read_byte, &write_byte, "../test/unit/state_tests_config", 250); + bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 250); syslog_libbidib(LOG_INFO, "bidib_feedback_tests: Feedback tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(feedback_system_error), diff --git a/test/unit/bidib_highlevel_message_tests.c b/test/unit/bidib_highlevel_message_tests.c index 3da86fd..2b24fd2 100644 --- a/test/unit/bidib_highlevel_message_tests.c +++ b/test/unit/bidib_highlevel_message_tests.c @@ -54,6 +54,15 @@ static void write_byte(uint8_t msg_byte) { output_index++; } +static void write_bytes(uint8_t* msg, int32_t len) { + if (msg != NULL && len > 0) { + for (int32_t i = 0; i < len; ++i) { + output_buffer[output_index] = msg[i]; + output_index++; + } + } +} + // Assume that the system receives a response to its request. static void board_receives_response(const uint8_t response_type) { pthread_rwlock_wrlock(&bidib_state_boards_rwlock); @@ -212,7 +221,7 @@ static void request_reverser_update_correctly(void **state __attribute__((unused int main(void) { bidib_set_lowlevel_debug_mode(true); - if (!bidib_start_pointer(&read_byte, &write_byte, "../test/unit/state_tests_config", 0)) { + if (!bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 0)) { set_all_boards_and_trains_connected(); syslog_libbidib(LOG_INFO, "bidib_highlevel_message_tests: Highlevel message tests started"); const struct CMUnitTest tests[] = { diff --git a/test/unit/bidib_lowlevel_message_tests.c b/test/unit/bidib_lowlevel_message_tests.c index 85d556a..1e6197f 100644 --- a/test/unit/bidib_lowlevel_message_tests.c +++ b/test/unit/bidib_lowlevel_message_tests.c @@ -50,6 +50,15 @@ static void write_byte(uint8_t msg_byte) { output_index++; } +static void write_bytes(uint8_t* msg, int32_t len) { + if (msg != NULL && len > 0) { + for (int32_t i = 0; i < len; ++i) { + output_buffer[output_index] = msg[i]; + output_index++; + } + } +} + static void vendor_data_set_correctly_send(void **state __attribute__((unused))) { t_bidib_node_address address = {0x01, 0x01, 0x00}; char *name = "Test"; @@ -173,7 +182,7 @@ static void bm_mirror_multiple_correctly_send(void **state __attribute__((unused int main(void) { bidib_set_lowlevel_debug_mode(true); - bidib_start_pointer(&read_byte, &write_byte, NULL, 0); + bidib_start_pointer(&read_byte, &write_byte, &write_bytes, NULL, 0); syslog_libbidib(LOG_INFO, "bidib_lowlevel_message_tests: %s", "Lowlevel message tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(vendor_data_set_correctly_send), diff --git a/test/unit/bidib_parallel_tests.c b/test/unit/bidib_parallel_tests.c index eb4f17e..5bc670e 100644 --- a/test/unit/bidib_parallel_tests.c +++ b/test/unit/bidib_parallel_tests.c @@ -57,6 +57,15 @@ static void write_byte(uint8_t msg_byte) { output_index++; } +static void write_bytes(uint8_t* msg, int32_t len) { + if (msg != NULL && len > 0) { + for (int32_t i = 0; i < len; ++i) { + output_buffer[output_index] = msg[i]; + output_index++; + } + } +} + static void set_all_boards_and_trains_connected(void) { pthread_rwlock_wrlock(&bidib_state_boards_rwlock); t_bidib_board *board_i; @@ -288,7 +297,7 @@ static void parallel_all(void **state __attribute__((unused))) { int main(void) { bidib_set_lowlevel_debug_mode(true); - if (!bidib_start_pointer(&read_byte, &write_byte, "../test/unit/state_tests_config", 0)) { + if (!bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 0)) { set_all_boards_and_trains_connected(); syslog_libbidib(LOG_INFO, "bidib_parallel_tests: Parallel tests started"); const struct CMUnitTest tests[] = { diff --git a/test/unit/bidib_receive_tests.c b/test/unit/bidib_receive_tests.c index 1479c5b..fca580e 100644 --- a/test/unit/bidib_receive_tests.c +++ b/test/unit/bidib_receive_tests.c @@ -55,6 +55,10 @@ static void write_byte(uint8_t byte __attribute__((unused))) { return; } +static void write_bytes(uint8_t* msg __attribute__((unused)), int32_t len __attribute__((unused))) { + return; +} + static void test_setup(void) { // two good messages in one packet input_buffer[0] = BIDIB_PKT_MAGIC; @@ -130,7 +134,7 @@ static void corrupted_packets_are_discarded_and_additional_pkt_magic_ignored(voi int main(void) { test_setup(); bidib_set_lowlevel_debug_mode(true); - bidib_start_pointer(&read_byte, &write_byte, NULL, 250); + bidib_start_pointer(&read_byte, &write_byte, &write_bytes, NULL, 250); syslog_libbidib(LOG_INFO, "bidib_receive_tests: %s", "Receive tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(packet_with_two_messages_correctly_handled), diff --git a/test/unit/bidib_send_tests.c b/test/unit/bidib_send_tests.c index 789358f..9d6939a 100644 --- a/test/unit/bidib_send_tests.c +++ b/test/unit/bidib_send_tests.c @@ -104,6 +104,15 @@ static void write_byte(uint8_t msg_byte) { output_buffer[output_index++] = msg_byte; } +static void write_bytes(uint8_t* msg, int32_t len) { + if (msg != NULL && len > 0) { + for (int32_t i = 0; i < len; ++i) { + output_buffer[output_index] = msg[i]; + output_index++; + } + } +} + static uint8_t read_byte(int *read_byte) { if (isWaiting) { *read_byte = 0; @@ -310,7 +319,7 @@ static void received_stall_zero_flushes_node_and_subnodes(void **state __attribu int main(void) { test_setup(); bidib_set_lowlevel_debug_mode(true); - bidib_start_pointer(&read_byte, &write_byte, NULL, 0); + bidib_start_pointer(&read_byte, &write_byte, &write_bytes, NULL, 0); syslog_libbidib(LOG_INFO, "bidib_send_tests: %s", "Send tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(first_message_is_buffered), diff --git a/test/unit/bidib_state_tests.c b/test/unit/bidib_state_tests.c index f8e8596..1854bae 100644 --- a/test/unit/bidib_state_tests.c +++ b/test/unit/bidib_state_tests.c @@ -81,6 +81,16 @@ static void write_byte(uint8_t byte) { output_buffer[output_index++] = byte; } +static void write_bytes(uint8_t* msg, int32_t len) { + static unsigned int output_index = 0; + if (msg != NULL && len > 0) { + for (int32_t i = 0; i < len; ++i) { + output_buffer[output_index] = msg[i]; + output_index++; + } + } +} + static void test_setup(void) { // response for protocol initialization input_buffer[0] = BIDIB_PKT_MAGIC; @@ -392,7 +402,7 @@ static void reverser_updates_state_correctly(void **state __attribute__((unused) int main(void) { test_setup(); - bidib_start_pointer(&read_byte, &write_byte, "../test/unit/state_tests_config", 250); + bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 250); syslog_libbidib(LOG_INFO, "bidib_state_tests: %s", "State tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(sys_reset_send_after_connection_is_established), From 9f9a0f77a999a41f6ce441bf6c1a2ad1d11162b3 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 10:29:49 +0200 Subject: [PATCH 02/51] new batch flush variants --- src/transmission/bidib_transmission_send.c | 203 ++++++++++++++++++++- 1 file changed, 201 insertions(+), 2 deletions(-) diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 4e41254..41a0f7a 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -38,6 +38,8 @@ #include "../../include/definitions/bidib_messages.h" #define PACKET_BUFFER_SIZE 256 +// Experiment? else delete. +#define PACKET_BUFFER_AUX_SIZE 312 pthread_mutex_t bidib_send_buffer_mutex; @@ -48,8 +50,13 @@ static void (*write_bytes)(uint8_t*, int32_t); volatile bool bidib_seq_num_enabled = true; static volatile unsigned int pkt_max_cap = 64; static volatile uint8_t buffer[PACKET_BUFFER_SIZE]; +static volatile uint8_t buffer_aux[PACKET_BUFFER_AUX_SIZE]; static volatile size_t buffer_index = 0; +typedef struct { + uint8_t *message; + size_t len; +} t_bidib_send_buff_arr; void bidib_set_write_dest(void (*write)(uint8_t)) { write_byte = write; @@ -81,11 +88,50 @@ static void bidib_send_byte(uint8_t b) { write_byte(b); } +/* +static size_t bidib_send_to_aux_buffer(uint8_t b, size_t aux_index) { + if (aux_index+2 >= PACKET_BUFFER_AUX_SIZE) { + // likely not enough space. (Pessimistic +2 because it might be escaped) + return 0; + } + size_t written = 1; + if ((b == BIDIB_PKT_MAGIC) || (b == BIDIB_PKT_ESCAPE)) { + buffer_aux[aux_index++] = (uint8_t) BIDIB_PKT_ESCAPE; + b = b ^ (uint8_t) 0x20; + written++; + } + buffer_aux[aux_index++] = b; + return written; +}*/ + +static t_bidib_send_buff_arr bidib_construct_sendbuffer_for_batch_write(size_t counted_escapes) { + if (buffer_index <= 0) { + return (t_bidib_send_buff_arr){NULL, 0}; + } + // Need to allocate buffer_index + escape_count bytes + t_bidib_send_buff_arr ret = {NULL, 0}; + ret.len = buffer_index + counted_escapes; + ret.message = malloc(sizeof(uint8_t) * ret.len); + if (counted_escapes == 0) { + memcpy(ret.message, (uint8_t*)buffer, sizeof(uint8_t) * ret.len); + } else { + size_t msg_i = 0; + for (size_t i = 0; i < buffer_index; ++i) { + uint8_t b = buffer[i]; + if (b == BIDIB_PKT_MAGIC || b == BIDIB_PKT_ESCAPE) { + ret.message[msg_i++] = BIDIB_PKT_ESCAPE; + b = b ^ (uint8_t) 0x20; + } + ret.message[msg_i++] = b; + } + } + return ret; +} + static void bidib_send_delimiter(void) { write_byte(BIDIB_PKT_MAGIC); } - // Must be called with bidib_send_buffer_mutex locked. static void bidib_flush_impl(void) { if (buffer_index > 0) { @@ -101,7 +147,160 @@ static void bidib_flush_impl(void) { // start-delimiter for next one buffer_index = 0; } - syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); + //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); +} + +// Must be called with bidib_send_buffer_mutex locked. +static void bidib_flush_batch_impl0(void) { + if (buffer_index > 0) { + uint8_t crc = 0; + int32_t aux_index = 0; + buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv + for (size_t i = 0; i < buffer_index; ++i) { + if (aux_index + 2 >= PACKET_BUFFER_AUX_SIZE) { + // Too big for flush_batch. Fallback to traditional one-by-one send. + bidib_flush_impl(); + return; + } + crc = bidib_crc_array[buffer[i] ^ crc]; + if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { + buffer_aux[aux_index++] = BIDIB_PKT_ESCAPE; + buffer_aux[aux_index++] = buffer[i] ^ (uint8_t) 0x20; + } else { + buffer_aux[aux_index++] = buffer[i]; + } + } + // pessimistic remaining size check + if (aux_index + 3 >= PACKET_BUFFER_AUX_SIZE) { + // Too big for flush_batch. Fallback to traditional one-by-one send. + bidib_flush_impl(); + return; + } + + // send crc byte (+ escape if necessary) + if (crc == BIDIB_PKT_MAGIC || crc == BIDIB_PKT_ESCAPE) { + buffer_aux[aux_index++] = BIDIB_PKT_ESCAPE; + buffer_aux[aux_index++] = crc ^ (uint8_t) 0x20; + } else { + buffer_aux[aux_index++] = crc; + } + buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv + + write_bytes((uint8_t*)buffer_aux, aux_index); + + buffer_index = 0; + } +} + +// Must be called with bidib_send_buffer_mutex locked. +static void bidib_flush_batch_impl1(void) { + if (buffer_index > 0) { + uint8_t crc = 0; + bidib_send_delimiter(); + size_t counted_escapes = 0; + for (size_t i = 0; i < buffer_index; i++) { + if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { + counted_escapes++; + } + crc = bidib_crc_array[buffer[i] ^ crc]; + } + t_bidib_send_buff_arr send_t = bidib_construct_sendbuffer_for_batch_write(counted_escapes); + write_bytes(send_t.message, (int32_t)send_t.len); + bidib_send_byte(crc); + bidib_send_delimiter(); + if (send_t.message != NULL) { + free(send_t.message); + } + // Could be optimized to use end-delimiter of last message also as + // start-delimiter for next one + buffer_index = 0; + } + //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); +} + +// Must be called with bidib_send_buffer_mutex locked. +static void bidib_flush_batch_impl2(void) { + if (buffer_index > 0) { + uint8_t crc = 0; + size_t counted_escapes = 0; + for (size_t i = 0; i < buffer_index; i++) { + if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { + counted_escapes++; + } + crc = bidib_crc_array[buffer[i] ^ crc]; + } + + t_bidib_send_buff_arr send_t = {NULL,0}; + // delim + buffer content + escape bytes + send_t.len = buffer_index + counted_escapes + 1; + send_t.message = malloc(sizeof(uint8_t) * send_t.len); + if (send_t.message == NULL) { + syslog_libbidib(LOG_ERR, "Cache flush failed, alloc failed"); + return; + } + size_t msg_i = 0; + send_t.message[msg_i++] = (uint8_t) BIDIB_PKT_MAGIC; // equiv bidib_send_delimiter(); + if (counted_escapes == 0) { + memcpy(&send_t.message[msg_i], (uint8_t*)buffer, sizeof(uint8_t) * buffer_index); + msg_i = msg_i + buffer_index; + } else { + for (size_t i = 0; i < buffer_index; ++i) { + uint8_t b = buffer[i]; + if (b == BIDIB_PKT_MAGIC || b == BIDIB_PKT_ESCAPE) { + send_t.message[msg_i++] = BIDIB_PKT_ESCAPE; + b = b ^ (uint8_t) 0x20; + } + send_t.message[msg_i++] = b; + } + } + write_bytes(send_t.message, (int32_t)send_t.len); + // Can't add crc to send_t.message without potential realloc if CRC happens to + // have the value of BIDIB_PKT_MAGIC or BIDIB_PKT_ESCAPE. + bidib_send_byte(crc); + bidib_send_delimiter(); + buffer_index = 0; + if (send_t.message != NULL) { + free(send_t.message); + } + } + //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); +} + +// Must be called with bidib_send_buffer_mutex locked. +static void bidib_flush_batch_impl3(void) { + if (buffer_index > 0) { + uint8_t crc = 0; + bidib_send_delimiter(); + size_t last_non_escaped_index = 0; + for (size_t i = 0; i < buffer_index; i++) { + if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { + if (last_non_escaped_index == i) { + // move index further as this index actually has to be escaped. + last_non_escaped_index = i + 1; + } else { + write_bytes((uint8_t*) buffer + last_non_escaped_index, i - last_non_escaped_index); + } + + bidib_send_byte(buffer[i]); + + last_non_escaped_index = i + 1; + } + crc = bidib_crc_array[buffer[i] ^ crc]; + } + if (last_non_escaped_index == 0) { + write_bytes((uint8_t*) buffer, buffer_index); + } else if (last_non_escaped_index < buffer_index) { + write_bytes((uint8_t*) buffer+last_non_escaped_index, buffer_index - last_non_escaped_index); + } else { + // All bytes from buffer already written. + } + bidib_send_byte(crc); + bidib_send_delimiter(); + // Could be optimized to use end-delimiter of last message also as + // start-delimiter for next one + buffer_index = 0; + } + //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); } void bidib_flush(void) { From 845ab0a9012b179c19c82c655c646b9cabba2a6f Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 12:40:22 +0200 Subject: [PATCH 03/51] change flush standard to batching --- src/transmission/bidib_transmission_send.c | 88 ++++++++++------------ 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 41a0f7a..6b52548 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -38,7 +38,6 @@ #include "../../include/definitions/bidib_messages.h" #define PACKET_BUFFER_SIZE 256 -// Experiment? else delete. #define PACKET_BUFFER_AUX_SIZE 312 @@ -88,52 +87,13 @@ static void bidib_send_byte(uint8_t b) { write_byte(b); } -/* -static size_t bidib_send_to_aux_buffer(uint8_t b, size_t aux_index) { - if (aux_index+2 >= PACKET_BUFFER_AUX_SIZE) { - // likely not enough space. (Pessimistic +2 because it might be escaped) - return 0; - } - size_t written = 1; - if ((b == BIDIB_PKT_MAGIC) || (b == BIDIB_PKT_ESCAPE)) { - buffer_aux[aux_index++] = (uint8_t) BIDIB_PKT_ESCAPE; - b = b ^ (uint8_t) 0x20; - written++; - } - buffer_aux[aux_index++] = b; - return written; -}*/ - -static t_bidib_send_buff_arr bidib_construct_sendbuffer_for_batch_write(size_t counted_escapes) { - if (buffer_index <= 0) { - return (t_bidib_send_buff_arr){NULL, 0}; - } - // Need to allocate buffer_index + escape_count bytes - t_bidib_send_buff_arr ret = {NULL, 0}; - ret.len = buffer_index + counted_escapes; - ret.message = malloc(sizeof(uint8_t) * ret.len); - if (counted_escapes == 0) { - memcpy(ret.message, (uint8_t*)buffer, sizeof(uint8_t) * ret.len); - } else { - size_t msg_i = 0; - for (size_t i = 0; i < buffer_index; ++i) { - uint8_t b = buffer[i]; - if (b == BIDIB_PKT_MAGIC || b == BIDIB_PKT_ESCAPE) { - ret.message[msg_i++] = BIDIB_PKT_ESCAPE; - b = b ^ (uint8_t) 0x20; - } - ret.message[msg_i++] = b; - } - } - return ret; -} static void bidib_send_delimiter(void) { write_byte(BIDIB_PKT_MAGIC); } // Must be called with bidib_send_buffer_mutex locked. -static void bidib_flush_impl(void) { +static void bidib_flush_impl_old(void) { if (buffer_index > 0) { uint8_t crc = 0; bidib_send_delimiter(); @@ -151,15 +111,15 @@ static void bidib_flush_impl(void) { } // Must be called with bidib_send_buffer_mutex locked. -static void bidib_flush_batch_impl0(void) { +static void bidib_flush_impl(void) { //bidib_flush_batch_impl0 if (buffer_index > 0) { uint8_t crc = 0; int32_t aux_index = 0; buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv for (size_t i = 0; i < buffer_index; ++i) { - if (aux_index + 2 >= PACKET_BUFFER_AUX_SIZE) { + if (aux_index + 3 >= PACKET_BUFFER_AUX_SIZE) { // Too big for flush_batch. Fallback to traditional one-by-one send. - bidib_flush_impl(); + bidib_flush_impl_old(); return; } crc = bidib_crc_array[buffer[i] ^ crc]; @@ -170,10 +130,11 @@ static void bidib_flush_batch_impl0(void) { buffer_aux[aux_index++] = buffer[i]; } } - // pessimistic remaining size check - if (aux_index + 3 >= PACKET_BUFFER_AUX_SIZE) { - // Too big for flush_batch. Fallback to traditional one-by-one send. - bidib_flush_impl(); + + if (aux_index + 4 >= PACKET_BUFFER_AUX_SIZE) { + // Too big for flush batch, can't fit crc+delim in aux buffer. + // Fallback to traditional one-by-one send. + bidib_flush_impl_old(); return; } @@ -191,6 +152,30 @@ static void bidib_flush_batch_impl0(void) { buffer_index = 0; } } +/* +static t_bidib_send_buff_arr bidib_construct_sendbuffer_for_batch_write(size_t counted_escapes) { + if (buffer_index <= 0) { + return (t_bidib_send_buff_arr){NULL, 0}; + } + // Need to allocate buffer_index + escape_count bytes + t_bidib_send_buff_arr ret = {NULL, 0}; + ret.len = buffer_index + counted_escapes; + ret.message = malloc(sizeof(uint8_t) * ret.len); + if (counted_escapes == 0) { + memcpy(ret.message, (uint8_t*)buffer, sizeof(uint8_t) * ret.len); + } else { + size_t msg_i = 0; + for (size_t i = 0; i < buffer_index; ++i) { + uint8_t b = buffer[i]; + if (b == BIDIB_PKT_MAGIC || b == BIDIB_PKT_ESCAPE) { + ret.message[msg_i++] = BIDIB_PKT_ESCAPE; + b = b ^ (uint8_t) 0x20; + } + ret.message[msg_i++] = b; + } + } + return ret; +} // Must be called with bidib_send_buffer_mutex locked. static void bidib_flush_batch_impl1(void) { @@ -302,16 +287,19 @@ static void bidib_flush_batch_impl3(void) { } //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); } - +*/ void bidib_flush(void) { struct timespec start, end; pthread_mutex_lock(&bidib_send_buffer_mutex); + bool smth_to_send = buffer_index > 0; clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_flush_impl(); clock_gettime(CLOCK_MONOTONIC_RAW, &end); pthread_mutex_unlock(&bidib_send_buffer_mutex); uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - syslog_libbidib(LOG_WARNING, "Flush took %llu us\n", delta_us); + if (smth_to_send) { + syslog_libbidib(LOG_WARNING, "Flush took %llu\n", delta_us); + } } void *bidib_auto_flush(void *interval) { From 55e36fee01fb7dd5d0c72c6aa09b8ee2186c7db0 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 13:02:03 +0200 Subject: [PATCH 04/51] adjusted physical test --- test/physical/swtbahn-full/testsuite.c | 26 +++++++++----------------- test/physical/test_common.c | 3 ++- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/test/physical/swtbahn-full/testsuite.c b/test/physical/swtbahn-full/testsuite.c index c2912c1..af3f2f6 100644 --- a/test/physical/swtbahn-full/testsuite.c +++ b/test/physical/swtbahn-full/testsuite.c @@ -324,9 +324,6 @@ static void *route99(void *arg) { testsuite_driveTo("seg46", 50, train1); sleep(1); testsuite_driveTo("seg46", 40, train1); - sleep(1); - testsuite_driveTo("seg46", 30, train1); - sleep(1); testsuite_driveToStop("seg47", 20, train1); sleep(5); @@ -395,30 +392,25 @@ static void *route100(void *arg) { sleep(1); - testsuite_driveTo("seg77", 126, train2); + testsuite_driveTo("seg77", 60, train2); testsuite_set_signal("signal43", "aspect_stop"); - testsuite_driveTo("seg26", 126, train2); + testsuite_driveTo("seg26", 60, train2); testsuite_set_signal("signal19", "aspect_stop"); - testsuite_driveTo("seg1", 126, train2); + testsuite_driveTo("seg1", 60, train2); testsuite_set_signal("signal3", "aspect_stop"); testsuite_set_signal("signal1", "aspect_stop"); - testsuite_driveTo("seg15", 126, train2); + testsuite_driveTo("seg15", 60, train2); testsuite_set_signal("signal13", "aspect_stop"); testsuite_set_signal("signal11", "aspect_stop"); - testsuite_driveTo("seg11", 126, train2); + testsuite_driveTo("seg11", 60, train2); testsuite_set_signal("signal10", "aspect_stop"); testsuite_set_signal("signal8", "aspect_stop"); testsuite_driveTo("seg31b", 50, train2); - sleep(1); - testsuite_driveTo("seg31b", 40, train2); - sleep(1); - testsuite_driveTo("seg31a", 30, train2); - sleep(1); testsuite_driveToStop("seg31a", 20, train2); sleep(5); @@ -436,18 +428,18 @@ static void *route100(void *arg) { sleep(1); - testsuite_driveTo("seg32", -126, train2); + testsuite_driveTo("seg32", -60, train2); testsuite_set_signal("signal22a", "aspect_stop"); testsuite_set_signal("signal22b", "aspect_stop"); - testsuite_driveTo("seg13", -126, train2); + testsuite_driveTo("seg13", -60, train2); testsuite_set_signal("signal9", "aspect_stop"); - testsuite_driveTo("seg17", -126, train2); + testsuite_driveTo("seg17", -60, train2); testsuite_set_signal("signal12", "aspect_stop"); testsuite_set_signal("signal14", "aspect_stop"); - testsuite_driveTo("seg3", -126, train2); + testsuite_driveTo("seg3", -60, train2); testsuite_set_signal("signal2", "aspect_stop"); testsuite_set_signal("signal4a", "aspect_stop"); testsuite_set_signal("signal4b", "aspect_stop"); diff --git a/test/physical/test_common.c b/test/physical/test_common.c index 5ae7455..8dfc27e 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -182,14 +182,15 @@ bool testsuite_trainReady(const char *train, const char *segment) { } void testsuite_driveTo(const char *segment, int speed, const char *train) { + syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d", train, segment, speed); bidib_set_train_speed(train, speed, "master"); bidib_flush(); - while (1) { t_bidib_train_position_query trainPosition = bidib_get_train_position(train); for (size_t i = 0; i < trainPosition.length; i++) { if (!strcmp(segment, trainPosition.segments[i])) { bidib_free_train_position_query(trainPosition); + syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - REACHED TARGET", train, segment, speed); return; } } From 27c30b1d940c8feebb99e857b2adfb20d42c7751 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 13:09:31 +0200 Subject: [PATCH 05/51] further testsuite adjustments --- test/physical/swtbahn-full/testsuite.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/physical/swtbahn-full/testsuite.c b/test/physical/swtbahn-full/testsuite.c index af3f2f6..b13b383 100644 --- a/test/physical/swtbahn-full/testsuite.c +++ b/test/physical/swtbahn-full/testsuite.c @@ -411,7 +411,7 @@ static void *route100(void *arg) { testsuite_set_signal("signal8", "aspect_stop"); testsuite_driveTo("seg31b", 50, train2); - testsuite_driveToStop("seg31a", 20, train2); + testsuite_driveToStop("seg31a", 40, train2); sleep(5); @@ -444,16 +444,10 @@ static void *route100(void *arg) { testsuite_set_signal("signal4a", "aspect_stop"); testsuite_set_signal("signal4b", "aspect_stop"); - testsuite_driveTo("seg28", -50, train2); + testsuite_driveTo("seg28", -40, train2); testsuite_set_signal("signal20", "aspect_stop"); - testsuite_driveTo("seg78a", -50, train2); - sleep(1); - testsuite_driveTo("seg78a", -40, train2); - sleep(1); - testsuite_driveTo("seg78a", -30, train2); - sleep(1); - testsuite_driveToStop("seg78a", -20, train2); + testsuite_driveToStop("seg78a", -40, train2); sleep(5); } From df633488c2be3666440ce3c1fb211c8331848194 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 13:19:57 +0200 Subject: [PATCH 06/51] fix track cov test case running forever --- test/physical/swtbahn-full/testsuite.c | 312 ++++++++++++------------- 1 file changed, 155 insertions(+), 157 deletions(-) diff --git a/test/physical/swtbahn-full/testsuite.c b/test/physical/swtbahn-full/testsuite.c index b13b383..4a7c0b5 100644 --- a/test/physical/swtbahn-full/testsuite.c +++ b/test/physical/swtbahn-full/testsuite.c @@ -285,78 +285,77 @@ static void *route99(void *arg) { pthread_exit(NULL); } - while (true) { - // train1: forwards - testsuite_switch_point("point22", "reverse"); - testsuite_switch_point("point23", "normal"); - testsuite_switch_point("point24", "reverse"); - testsuite_switch_point("point12", "reverse"); - testsuite_switch_point("point13", "reverse"); - testsuite_switch_point("point14", "reverse"); - testsuite_switch_point("point15", "normal"); - testsuite_switch_point("point16", "reverse"); - testsuite_switch_point("point21", "reverse"); - testsuite_switch_point("point20", "normal"); - testsuite_switch_point("point19", "normal"); - testsuite_switch_point("point18b", "reverse"); - - sleep(1); - - testsuite_set_signal("signal30", "aspect_go"); - testsuite_set_signal("signal33", "aspect_go"); - testsuite_set_signal("signal35a", "aspect_go"); - testsuite_set_signal("signal35b", "aspect_go"); - testsuite_set_signal("signal37", "aspect_go"); - - sleep(1); - - testsuite_driveTo("seg57", 50, train1); - testsuite_set_signal("signal30", "aspect_stop"); - - testsuite_driveTo("seg64", 50, train1); - testsuite_set_signal("signal33", "aspect_stop"); - testsuite_set_signal("signal35a", "aspect_stop"); - testsuite_set_signal("signal35b", "aspect_stop"); - - testsuite_driveTo("seg69", 50, train1); - testsuite_set_signal("signal37", "aspect_stop"); - - testsuite_driveTo("seg46", 50, train1); - sleep(1); - testsuite_driveTo("seg46", 40, train1); - testsuite_driveToStop("seg47", 20, train1); - - sleep(5); - - // train1: backwards - testsuite_set_signal("signal26", "aspect_go"); - testsuite_set_signal("signal38", "aspect_go"); - testsuite_set_signal("signal36", "aspect_go"); - testsuite_set_signal("signal34", "aspect_go"); - testsuite_set_signal("signal32", "aspect_go"); - - sleep(1); - - testsuite_driveTo("seg45", -50, train1); - testsuite_set_signal("signal26", "aspect_stop"); - - testsuite_driveTo("seg67", -50, train1); - testsuite_set_signal("signal38", "aspect_stop"); - testsuite_set_signal("signal36", "aspect_stop"); - - testsuite_driveTo("seg62", -50, train1); - testsuite_set_signal("signal34", "aspect_stop"); - testsuite_set_signal("signal32", "aspect_stop"); - - testsuite_driveTo("seg60", -50, train1); - testsuite_driveTo("seg53", -40, train1); - testsuite_driveTo("seg57", -30, train1); - testsuite_driveTo("seg58", -20, train1); - sleep(2); - testsuite_driveToStop("seg58", -20, train1); - - sleep(5); - } + // train1: forwards + testsuite_switch_point("point22", "reverse"); + testsuite_switch_point("point23", "normal"); + testsuite_switch_point("point24", "reverse"); + testsuite_switch_point("point12", "reverse"); + testsuite_switch_point("point13", "reverse"); + testsuite_switch_point("point14", "reverse"); + testsuite_switch_point("point15", "normal"); + testsuite_switch_point("point16", "reverse"); + testsuite_switch_point("point21", "reverse"); + testsuite_switch_point("point20", "normal"); + testsuite_switch_point("point19", "normal"); + testsuite_switch_point("point18b", "reverse"); + + sleep(1); + + testsuite_set_signal("signal30", "aspect_go"); + testsuite_set_signal("signal33", "aspect_go"); + testsuite_set_signal("signal35a", "aspect_go"); + testsuite_set_signal("signal35b", "aspect_go"); + testsuite_set_signal("signal37", "aspect_go"); + + sleep(1); + + testsuite_driveTo("seg57", 50, train1); + testsuite_set_signal("signal30", "aspect_stop"); + + testsuite_driveTo("seg64", 50, train1); + testsuite_set_signal("signal33", "aspect_stop"); + testsuite_set_signal("signal35a", "aspect_stop"); + testsuite_set_signal("signal35b", "aspect_stop"); + + testsuite_driveTo("seg69", 50, train1); + testsuite_set_signal("signal37", "aspect_stop"); + + testsuite_driveTo("seg46", 50, train1); + sleep(1); + testsuite_driveTo("seg46", 40, train1); + testsuite_driveToStop("seg47", 20, train1); + + sleep(5); + + // train1: backwards + testsuite_set_signal("signal26", "aspect_go"); + testsuite_set_signal("signal38", "aspect_go"); + testsuite_set_signal("signal36", "aspect_go"); + testsuite_set_signal("signal34", "aspect_go"); + testsuite_set_signal("signal32", "aspect_go"); + + sleep(1); + + testsuite_driveTo("seg45", -50, train1); + testsuite_set_signal("signal26", "aspect_stop"); + + testsuite_driveTo("seg67", -50, train1); + testsuite_set_signal("signal38", "aspect_stop"); + testsuite_set_signal("signal36", "aspect_stop"); + + testsuite_driveTo("seg62", -50, train1); + testsuite_set_signal("signal34", "aspect_stop"); + testsuite_set_signal("signal32", "aspect_stop"); + + testsuite_driveTo("seg60", -50, train1); + testsuite_driveTo("seg53", -40, train1); + testsuite_driveTo("seg57", -30, train1); + testsuite_driveTo("seg58", -20, train1); + sleep(2); + testsuite_driveToStop("seg58", -20, train1); + + sleep(5); + pthread_exit(NULL); } static void *route100(void *arg) { @@ -366,91 +365,90 @@ static void *route100(void *arg) { pthread_exit(NULL); } - while (true) { - // train2: forwards - testsuite_switch_point("point10", "reverse"); - testsuite_switch_point("point9", "normal"); - testsuite_switch_point("point8", "reverse"); - testsuite_switch_point("point1", "reverse"); - testsuite_switch_point("point7", "normal"); - testsuite_switch_point("point6", "normal"); - testsuite_switch_point("point5", "normal"); - testsuite_switch_point("point4", "normal"); - testsuite_switch_point("point3", "reverse"); - testsuite_switch_point("point11", "reverse"); - - sleep(1); - - testsuite_set_signal("signal43", "aspect_shunt"); - testsuite_set_signal("signal19", "aspect_go"); - testsuite_set_signal("signal3", "aspect_go"); - testsuite_set_signal("signal1", "aspect_go"); - testsuite_set_signal("signal13", "aspect_go"); - testsuite_set_signal("signal11", "aspect_go"); - testsuite_set_signal("signal10", "aspect_go"); - testsuite_set_signal("signal8", "aspect_go"); - - sleep(1); - - testsuite_driveTo("seg77", 60, train2); - testsuite_set_signal("signal43", "aspect_stop"); - - testsuite_driveTo("seg26", 60, train2); - testsuite_set_signal("signal19", "aspect_stop"); - - testsuite_driveTo("seg1", 60, train2); - testsuite_set_signal("signal3", "aspect_stop"); - testsuite_set_signal("signal1", "aspect_stop"); - - testsuite_driveTo("seg15", 60, train2); - testsuite_set_signal("signal13", "aspect_stop"); - testsuite_set_signal("signal11", "aspect_stop"); - - testsuite_driveTo("seg11", 60, train2); - testsuite_set_signal("signal10", "aspect_stop"); - testsuite_set_signal("signal8", "aspect_stop"); - - testsuite_driveTo("seg31b", 50, train2); - testsuite_driveToStop("seg31a", 40, train2); - - sleep(5); - - // train2: backwards - testsuite_set_signal("signal22a", "aspect_go"); - testsuite_set_signal("signal22b", "aspect_go"); - testsuite_set_signal("signal9", "aspect_go"); - testsuite_set_signal("signal12", "aspect_go"); - testsuite_set_signal("signal14", "aspect_go"); - testsuite_set_signal("signal2", "aspect_go"); - testsuite_set_signal("signal4a", "aspect_go"); - testsuite_set_signal("signal4b", "aspect_go"); - testsuite_set_signal("signal20", "aspect_shunt"); - - sleep(1); - - testsuite_driveTo("seg32", -60, train2); - testsuite_set_signal("signal22a", "aspect_stop"); - testsuite_set_signal("signal22b", "aspect_stop"); - - testsuite_driveTo("seg13", -60, train2); - testsuite_set_signal("signal9", "aspect_stop"); - - testsuite_driveTo("seg17", -60, train2); - testsuite_set_signal("signal12", "aspect_stop"); - testsuite_set_signal("signal14", "aspect_stop"); - - testsuite_driveTo("seg3", -60, train2); - testsuite_set_signal("signal2", "aspect_stop"); - testsuite_set_signal("signal4a", "aspect_stop"); - testsuite_set_signal("signal4b", "aspect_stop"); - - testsuite_driveTo("seg28", -40, train2); - testsuite_set_signal("signal20", "aspect_stop"); - - testsuite_driveToStop("seg78a", -40, train2); - - sleep(5); - } + // train2: forwards + testsuite_switch_point("point10", "reverse"); + testsuite_switch_point("point9", "normal"); + testsuite_switch_point("point8", "reverse"); + testsuite_switch_point("point1", "reverse"); + testsuite_switch_point("point7", "normal"); + testsuite_switch_point("point6", "normal"); + testsuite_switch_point("point5", "normal"); + testsuite_switch_point("point4", "normal"); + testsuite_switch_point("point3", "reverse"); + testsuite_switch_point("point11", "reverse"); + + sleep(1); + + testsuite_set_signal("signal43", "aspect_shunt"); + testsuite_set_signal("signal19", "aspect_go"); + testsuite_set_signal("signal3", "aspect_go"); + testsuite_set_signal("signal1", "aspect_go"); + testsuite_set_signal("signal13", "aspect_go"); + testsuite_set_signal("signal11", "aspect_go"); + testsuite_set_signal("signal10", "aspect_go"); + testsuite_set_signal("signal8", "aspect_go"); + + sleep(1); + + testsuite_driveTo("seg77", 60, train2); + testsuite_set_signal("signal43", "aspect_stop"); + + testsuite_driveTo("seg26", 60, train2); + testsuite_set_signal("signal19", "aspect_stop"); + + testsuite_driveTo("seg1", 60, train2); + testsuite_set_signal("signal3", "aspect_stop"); + testsuite_set_signal("signal1", "aspect_stop"); + + testsuite_driveTo("seg15", 60, train2); + testsuite_set_signal("signal13", "aspect_stop"); + testsuite_set_signal("signal11", "aspect_stop"); + + testsuite_driveTo("seg11", 60, train2); + testsuite_set_signal("signal10", "aspect_stop"); + testsuite_set_signal("signal8", "aspect_stop"); + + testsuite_driveTo("seg31b", 50, train2); + testsuite_driveToStop("seg31a", 40, train2); + + sleep(5); + + // train2: backwards + testsuite_set_signal("signal22a", "aspect_go"); + testsuite_set_signal("signal22b", "aspect_go"); + testsuite_set_signal("signal9", "aspect_go"); + testsuite_set_signal("signal12", "aspect_go"); + testsuite_set_signal("signal14", "aspect_go"); + testsuite_set_signal("signal2", "aspect_go"); + testsuite_set_signal("signal4a", "aspect_go"); + testsuite_set_signal("signal4b", "aspect_go"); + testsuite_set_signal("signal20", "aspect_shunt"); + + sleep(1); + + testsuite_driveTo("seg32", -60, train2); + testsuite_set_signal("signal22a", "aspect_stop"); + testsuite_set_signal("signal22b", "aspect_stop"); + + testsuite_driveTo("seg13", -60, train2); + testsuite_set_signal("signal9", "aspect_stop"); + + testsuite_driveTo("seg17", -60, train2); + testsuite_set_signal("signal12", "aspect_stop"); + testsuite_set_signal("signal14", "aspect_stop"); + + testsuite_driveTo("seg3", -60, train2); + testsuite_set_signal("signal2", "aspect_stop"); + testsuite_set_signal("signal4a", "aspect_stop"); + testsuite_set_signal("signal4b", "aspect_stop"); + + testsuite_driveTo("seg28", -40, train2); + testsuite_set_signal("signal20", "aspect_stop"); + + testsuite_driveToStop("seg78a", -40, train2); + + sleep(5); + pthread_exit(NULL); } void testsuite_case_swtbahnFullMultipleTrains(const char *train1, const char *train2) { From 4cd55dc81654af0bf436b4ca810fefec99778d22 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 14:46:27 +0200 Subject: [PATCH 07/51] tuned receive thread reading --- src/transmission/bidib_transmission_receive.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 7ce7088..fde239d 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -733,7 +733,8 @@ static void bidib_receive_packet(void) { while (bidib_running && !bidib_discard_rx) { data = read_byte(&read_byte_success); while (!read_byte_success) { - usleep(5000); // 0.005s + //usleep(5000); // 0.005s + usleep(500); // 0.0005s data = read_byte(&read_byte_success); if (!bidib_running || bidib_discard_rx) { return; @@ -742,10 +743,9 @@ static void bidib_receive_packet(void) { read_byte_success = 0; if (data == BIDIB_PKT_MAGIC) { - if (buffer_index == 0) { - continue; + if (buffer_index != 0) { + break; } - break; } else if (data == BIDIB_PKT_ESCAPE) { // Next byte is escaped escape_hot = true; @@ -765,10 +765,10 @@ static void bidib_receive_packet(void) { return; } - syslog_libbidib(LOG_DEBUG, "%s", "Received packet"); + //syslog_libbidib(LOG_DEBUG, "%s", "Received packet"); if (crc == 0x00) { - syslog_libbidib(LOG_DEBUG, "%s", "CRC correct, split packet in messages"); + //syslog_libbidib(LOG_DEBUG, "%s", "CRC correct, split packet in messages"); // Split packet in messages and add them to queue, exclude crc sum buffer_index--; bidib_split_packet(buffer, buffer_index); From 2fdb0a308daec8fb498429e23498e79ee9b66e5b Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 14:53:35 +0200 Subject: [PATCH 08/51] log if receive-packet takes longer than 0.1s --- src/transmission/bidib_transmission_receive.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index fde239d..ceb8e52 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -806,8 +806,15 @@ static void bidib_receive_first_pkt_magic(void) { void *bidib_auto_receive(void *par __attribute__((unused))) { while (bidib_running) { bidib_receive_first_pkt_magic(); + struct timespec start, end; while (bidib_running && !bidib_discard_rx) { + clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_receive_packet(); + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + if (delta_us > 100000) { // > 0.1s + syslog_libbidib(LOG_WARNING, "bidib_receive_packet took long - %llu us\n", delta_us); + } } } return NULL; From 615c8c02a7b532bec2a82bf75480fb27bcab0020 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:01:46 +0200 Subject: [PATCH 09/51] handle receive benchmarking --- src/transmission/bidib_transmission_receive.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index ceb8e52..3f14591 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -684,7 +684,7 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) { // j tracks the message size in terms of buffer elements. size_t j = 0; - + struct timespec start, end; for (size_t i = 0; i < buffer_size; i += j) { // Length of message data is defined in buffer[i]. // Message data starts at buffer[i + 1] @@ -715,8 +715,18 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) } } } + clock_gettime(CLOCK_MONOTONIC_RAW, &start); unsigned int action_id = bidib_node_state_update(addr_stack, type); + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t node_update_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_handle_received_message(message, type, addr_stack, msg_seqnum, action_id); + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t handle_receive_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + if (node_update_delta_us + handle_receive_delta_us > 100000) { + syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_delta_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us\n", handle_receive_delta_us); + } } } From 39ce1d92e6c34d37ebd2f4e5514443dfe2b633e7 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:05:51 +0200 Subject: [PATCH 10/51] more split packet time logging --- src/transmission/bidib_transmission_receive.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 3f14591..0e7b5d1 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -686,6 +686,7 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) size_t j = 0; struct timespec start, end; for (size_t i = 0; i < buffer_size; i += j) { + clock_gettime(CLOCK_MONOTONIC_RAW, &start); // Length of message data is defined in buffer[i]. // Message data starts at buffer[i + 1] // and ends at buffer[i + buffer[i]]. @@ -715,6 +716,8 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) } } } + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t msg_read_in_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; clock_gettime(CLOCK_MONOTONIC_RAW, &start); unsigned int action_id = bidib_node_state_update(addr_stack, type); clock_gettime(CLOCK_MONOTONIC_RAW, &end); @@ -723,8 +726,9 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) bidib_handle_received_message(message, type, addr_stack, msg_seqnum, action_id); clock_gettime(CLOCK_MONOTONIC_RAW, &end); uint64_t handle_receive_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (node_update_delta_us + handle_receive_delta_us > 100000) { - syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_delta_us); + if (msg_read_in_delta_us + node_update_delta_us + handle_receive_delta_us > 100000) { + syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us\n", msg_read_in_delta_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_delta_us); syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us\n", handle_receive_delta_us); } } @@ -754,7 +758,7 @@ static void bidib_receive_packet(void) { if (data == BIDIB_PKT_MAGIC) { if (buffer_index != 0) { - break; + break; // End of msg } } else if (data == BIDIB_PKT_ESCAPE) { // Next byte is escaped From 09e752d38c860429ed2cac7faebfed5d6fb05978 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:09:07 +0200 Subject: [PATCH 11/51] more time logging --- src/transmission/bidib_transmission_receive.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 0e7b5d1..6d525a7 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -742,7 +742,8 @@ static void bidib_receive_packet(void) { size_t buffer_index = 0; bool escape_hot = false; uint8_t crc = 0x00; - + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); // Read the packet bytes while (bidib_running && !bidib_discard_rx) { data = read_byte(&read_byte_success); @@ -774,7 +775,12 @@ static void bidib_receive_packet(void) { buffer_index++; } } - + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + if (delta_us > 100000) { + syslog_libbidib(LOG_WARNING, "receive_packet reading packet bytes took %llu\n", delta_us); + } + if (!bidib_running || bidib_discard_rx) { return; } From 914ddb6510993b81d397480e28fa0beee12955fe Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:17:18 +0200 Subject: [PATCH 12/51] time logging --- src/transmission/bidib_transmission_receive.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 6d525a7..8c78943 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -743,7 +743,7 @@ static void bidib_receive_packet(void) { bool escape_hot = false; uint8_t crc = 0x00; struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); + clock_gettime(CLOCK_MONOTONIC_RAW, &start); // to make sure it's set // Read the packet bytes while (bidib_running && !bidib_discard_rx) { data = read_byte(&read_byte_success); @@ -760,6 +760,9 @@ static void bidib_receive_packet(void) { if (data == BIDIB_PKT_MAGIC) { if (buffer_index != 0) { break; // End of msg + } else { + // Start of message, i.e. first byte received. + clock_gettime(CLOCK_MONOTONIC_RAW, &start); } } else if (data == BIDIB_PKT_ESCAPE) { // Next byte is escaped @@ -778,7 +781,7 @@ static void bidib_receive_packet(void) { clock_gettime(CLOCK_MONOTONIC_RAW, &end); uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; if (delta_us > 100000) { - syslog_libbidib(LOG_WARNING, "receive_packet reading packet bytes took %llu\n", delta_us); + syslog_libbidib(LOG_WARNING, "receive_packet reading packet bytes took %llu us from reading of first byte\n", delta_us); } if (!bidib_running || bidib_discard_rx) { From 1312b16b9b569429426615104b56502617c355b4 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:19:49 +0200 Subject: [PATCH 13/51] time logging ad. --- src/transmission/bidib_transmission_receive.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 8c78943..2f09f5b 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -743,7 +743,7 @@ static void bidib_receive_packet(void) { bool escape_hot = false; uint8_t crc = 0x00; struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); // to make sure it's set + bool start_set = false; // Read the packet bytes while (bidib_running && !bidib_discard_rx) { data = read_byte(&read_byte_success); @@ -762,6 +762,7 @@ static void bidib_receive_packet(void) { break; // End of msg } else { // Start of message, i.e. first byte received. + start_set = true; clock_gettime(CLOCK_MONOTONIC_RAW, &start); } } else if (data == BIDIB_PKT_ESCAPE) { @@ -778,10 +779,12 @@ static void bidib_receive_packet(void) { buffer_index++; } } - clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (delta_us > 100000) { - syslog_libbidib(LOG_WARNING, "receive_packet reading packet bytes took %llu us from reading of first byte\n", delta_us); + if (start_set) { + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + if (delta_us > 100000) { + syslog_libbidib(LOG_WARNING, "receive_packet reading packet bytes took %llu us from reading of first byte\n", delta_us); + } } if (!bidib_running || bidib_discard_rx) { From 6290bf68dfcabc6c443c7ba2517b2b2681aee124 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:21:26 +0200 Subject: [PATCH 14/51] time logging adjustment --- src/transmission/bidib_transmission_receive.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 2f09f5b..dc47ef2 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -756,14 +756,14 @@ static void bidib_receive_packet(void) { } } read_byte_success = 0; + if (!start_set) { + start_set = true; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); + } if (data == BIDIB_PKT_MAGIC) { if (buffer_index != 0) { break; // End of msg - } else { - // Start of message, i.e. first byte received. - start_set = true; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); } } else if (data == BIDIB_PKT_ESCAPE) { // Next byte is escaped From 11cddc7e7fadac28a7ff2c02e9815eed5095d0fb Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:25:40 +0200 Subject: [PATCH 15/51] adjusted "took long" threshold for auto receive thread --- src/transmission/bidib_transmission_receive.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index dc47ef2..3826dc7 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -791,7 +791,7 @@ static void bidib_receive_packet(void) { return; } - //syslog_libbidib(LOG_DEBUG, "%s", "Received packet"); + syslog_libbidib(LOG_DEBUG, "%s", "Received packet"); if (crc == 0x00) { //syslog_libbidib(LOG_DEBUG, "%s", "CRC correct, split packet in messages"); @@ -838,8 +838,8 @@ void *bidib_auto_receive(void *par __attribute__((unused))) { bidib_receive_packet(); clock_gettime(CLOCK_MONOTONIC_RAW, &end); uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (delta_us > 100000) { // > 0.1s - syslog_libbidib(LOG_WARNING, "bidib_receive_packet took long - %llu us\n", delta_us); + if (delta_us > 1000000) { // > 1s + syslog_libbidib(LOG_WARNING, "bidib_receive_packet took very long - %llu us\n", delta_us); } } } From 9b5ba56ec6e98015a2fc2d88a8fa538843270723 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 8 May 2024 15:33:33 +0200 Subject: [PATCH 16/51] stop logging every flush duration --- src/transmission/bidib_transmission_send.c | 151 ++------------------- 1 file changed, 8 insertions(+), 143 deletions(-) diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 6b52548..06fa488 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -152,154 +152,19 @@ static void bidib_flush_impl(void) { //bidib_flush_batch_impl0 buffer_index = 0; } } -/* -static t_bidib_send_buff_arr bidib_construct_sendbuffer_for_batch_write(size_t counted_escapes) { - if (buffer_index <= 0) { - return (t_bidib_send_buff_arr){NULL, 0}; - } - // Need to allocate buffer_index + escape_count bytes - t_bidib_send_buff_arr ret = {NULL, 0}; - ret.len = buffer_index + counted_escapes; - ret.message = malloc(sizeof(uint8_t) * ret.len); - if (counted_escapes == 0) { - memcpy(ret.message, (uint8_t*)buffer, sizeof(uint8_t) * ret.len); - } else { - size_t msg_i = 0; - for (size_t i = 0; i < buffer_index; ++i) { - uint8_t b = buffer[i]; - if (b == BIDIB_PKT_MAGIC || b == BIDIB_PKT_ESCAPE) { - ret.message[msg_i++] = BIDIB_PKT_ESCAPE; - b = b ^ (uint8_t) 0x20; - } - ret.message[msg_i++] = b; - } - } - return ret; -} -// Must be called with bidib_send_buffer_mutex locked. -static void bidib_flush_batch_impl1(void) { - if (buffer_index > 0) { - uint8_t crc = 0; - bidib_send_delimiter(); - size_t counted_escapes = 0; - for (size_t i = 0; i < buffer_index; i++) { - if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { - counted_escapes++; - } - crc = bidib_crc_array[buffer[i] ^ crc]; - } - t_bidib_send_buff_arr send_t = bidib_construct_sendbuffer_for_batch_write(counted_escapes); - write_bytes(send_t.message, (int32_t)send_t.len); - bidib_send_byte(crc); - bidib_send_delimiter(); - if (send_t.message != NULL) { - free(send_t.message); - } - // Could be optimized to use end-delimiter of last message also as - // start-delimiter for next one - buffer_index = 0; - } - //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); -} - -// Must be called with bidib_send_buffer_mutex locked. -static void bidib_flush_batch_impl2(void) { - if (buffer_index > 0) { - uint8_t crc = 0; - size_t counted_escapes = 0; - for (size_t i = 0; i < buffer_index; i++) { - if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { - counted_escapes++; - } - crc = bidib_crc_array[buffer[i] ^ crc]; - } - - t_bidib_send_buff_arr send_t = {NULL,0}; - // delim + buffer content + escape bytes - send_t.len = buffer_index + counted_escapes + 1; - send_t.message = malloc(sizeof(uint8_t) * send_t.len); - if (send_t.message == NULL) { - syslog_libbidib(LOG_ERR, "Cache flush failed, alloc failed"); - return; - } - size_t msg_i = 0; - send_t.message[msg_i++] = (uint8_t) BIDIB_PKT_MAGIC; // equiv bidib_send_delimiter(); - if (counted_escapes == 0) { - memcpy(&send_t.message[msg_i], (uint8_t*)buffer, sizeof(uint8_t) * buffer_index); - msg_i = msg_i + buffer_index; - } else { - for (size_t i = 0; i < buffer_index; ++i) { - uint8_t b = buffer[i]; - if (b == BIDIB_PKT_MAGIC || b == BIDIB_PKT_ESCAPE) { - send_t.message[msg_i++] = BIDIB_PKT_ESCAPE; - b = b ^ (uint8_t) 0x20; - } - send_t.message[msg_i++] = b; - } - } - write_bytes(send_t.message, (int32_t)send_t.len); - // Can't add crc to send_t.message without potential realloc if CRC happens to - // have the value of BIDIB_PKT_MAGIC or BIDIB_PKT_ESCAPE. - bidib_send_byte(crc); - bidib_send_delimiter(); - buffer_index = 0; - if (send_t.message != NULL) { - free(send_t.message); - } - } - //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); -} - -// Must be called with bidib_send_buffer_mutex locked. -static void bidib_flush_batch_impl3(void) { - if (buffer_index > 0) { - uint8_t crc = 0; - bidib_send_delimiter(); - size_t last_non_escaped_index = 0; - for (size_t i = 0; i < buffer_index; i++) { - if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { - if (last_non_escaped_index == i) { - // move index further as this index actually has to be escaped. - last_non_escaped_index = i + 1; - } else { - write_bytes((uint8_t*) buffer + last_non_escaped_index, i - last_non_escaped_index); - } - - bidib_send_byte(buffer[i]); - - last_non_escaped_index = i + 1; - } - crc = bidib_crc_array[buffer[i] ^ crc]; - } - if (last_non_escaped_index == 0) { - write_bytes((uint8_t*) buffer, buffer_index); - } else if (last_non_escaped_index < buffer_index) { - write_bytes((uint8_t*) buffer+last_non_escaped_index, buffer_index - last_non_escaped_index); - } else { - // All bytes from buffer already written. - } - bidib_send_byte(crc); - bidib_send_delimiter(); - // Could be optimized to use end-delimiter of last message also as - // start-delimiter for next one - buffer_index = 0; - } - //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); -} -*/ void bidib_flush(void) { - struct timespec start, end; + //struct timespec start, end; pthread_mutex_lock(&bidib_send_buffer_mutex); - bool smth_to_send = buffer_index > 0; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); + //bool smth_to_send = buffer_index > 0; + //clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_flush_impl(); - clock_gettime(CLOCK_MONOTONIC_RAW, &end); + //clock_gettime(CLOCK_MONOTONIC_RAW, &end); pthread_mutex_unlock(&bidib_send_buffer_mutex); - uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (smth_to_send) { - syslog_libbidib(LOG_WARNING, "Flush took %llu\n", delta_us); - } + //uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + //if (smth_to_send) { + // syslog_libbidib(LOG_WARNING, "Flush took %llu\n", delta_us); + //} } void *bidib_auto_flush(void *interval) { From cd788cb73646ea38db3b6392058f2183c7ac0b72 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 26 Nov 2024 15:41:59 +0100 Subject: [PATCH 17/51] documentation improved for additions and removed commented out code --- src/transmission/bidib_transmission_receive.c | 42 ++++++------------- src/transmission/bidib_transmission_send.c | 38 ++++++++++------- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 3826dc7..b28163d 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -717,19 +717,22 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) } } clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t msg_read_in_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + uint64_t msg_read_in_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; clock_gettime(CLOCK_MONOTONIC_RAW, &start); unsigned int action_id = bidib_node_state_update(addr_stack, type); clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t node_update_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + uint64_t node_update_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_handle_received_message(message, type, addr_stack, msg_seqnum, action_id); clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t handle_receive_delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (msg_read_in_delta_us + node_update_delta_us + handle_receive_delta_us > 100000) { - syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us\n", msg_read_in_delta_us); - syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_delta_us); - syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us\n", handle_receive_delta_us); + uint64_t handle_receive_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + const uint64_t slow_processing_threshold_us = 100000; // 0.1 s + if (msg_read_in_us + node_update_us + handle_receive_us > slow_processing_threshold_us) { + // In case the processing steps above take above the specified threshold, + // i.e., longer than expected, log the time taken for each of the three steps. + syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us\n", msg_read_in_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us\n", handle_receive_us); } } } @@ -742,24 +745,18 @@ static void bidib_receive_packet(void) { size_t buffer_index = 0; bool escape_hot = false; uint8_t crc = 0x00; - struct timespec start, end; - bool start_set = false; + // Read the packet bytes while (bidib_running && !bidib_discard_rx) { data = read_byte(&read_byte_success); while (!read_byte_success) { - //usleep(5000); // 0.005s - usleep(500); // 0.0005s + usleep(5000); // 0.005s data = read_byte(&read_byte_success); if (!bidib_running || bidib_discard_rx) { return; } } read_byte_success = 0; - if (!start_set) { - start_set = true; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); - } if (data == BIDIB_PKT_MAGIC) { if (buffer_index != 0) { @@ -779,13 +776,6 @@ static void bidib_receive_packet(void) { buffer_index++; } } - if (start_set) { - clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (delta_us > 100000) { - syslog_libbidib(LOG_WARNING, "receive_packet reading packet bytes took %llu us from reading of first byte\n", delta_us); - } - } if (!bidib_running || bidib_discard_rx) { return; @@ -794,7 +784,6 @@ static void bidib_receive_packet(void) { syslog_libbidib(LOG_DEBUG, "%s", "Received packet"); if (crc == 0x00) { - //syslog_libbidib(LOG_DEBUG, "%s", "CRC correct, split packet in messages"); // Split packet in messages and add them to queue, exclude crc sum buffer_index--; bidib_split_packet(buffer, buffer_index); @@ -832,15 +821,8 @@ static void bidib_receive_first_pkt_magic(void) { void *bidib_auto_receive(void *par __attribute__((unused))) { while (bidib_running) { bidib_receive_first_pkt_magic(); - struct timespec start, end; while (bidib_running && !bidib_discard_rx) { - clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_receive_packet(); - clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (delta_us > 1000000) { // > 1s - syslog_libbidib(LOG_WARNING, "bidib_receive_packet took very long - %llu us\n", delta_us); - } } } return NULL; diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 06fa488..2e76481 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -52,11 +52,6 @@ static volatile uint8_t buffer[PACKET_BUFFER_SIZE]; static volatile uint8_t buffer_aux[PACKET_BUFFER_AUX_SIZE]; static volatile size_t buffer_index = 0; -typedef struct { - uint8_t *message; - size_t len; -} t_bidib_send_buff_arr; - void bidib_set_write_dest(void (*write)(uint8_t)) { write_byte = write; syslog_libbidib(LOG_INFO, "%s", "Write function was set"); @@ -107,16 +102,32 @@ static void bidib_flush_impl_old(void) { // start-delimiter for next one buffer_index = 0; } - //syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); + syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); } -// Must be called with bidib_send_buffer_mutex locked. -static void bidib_flush_impl(void) { //bidib_flush_batch_impl0 +/** + * @brief Will flush the send cache, if possible in once go (as one batch); + * if batching not possible, then send byte-per-byte. + * Must be called with bidib_send_buffer_mutex locked. + * + * How does it work? It copies the actual buffer (called `buffer`) + * byte-per-byte to an auxiliary buffer (called `buffer_aux`), + * and whilst doing so it computes the crc and adds/inserts the crc and escape + * related bytes/chars where needed. + * Due the need to insert bytes (e.g., related to the crc or escapes), we can't + * modify the `buffer` in-place. The solution with an auxiliary buffer + * has been compared against solutions with dynamic memory allocation, + * where the auxiliary buffer solution has shown to be faster, more timing-predictable, + * and easier to maintain/less risk of a memory leak. + * + */ +static void bidib_flush_impl(void) { if (buffer_index > 0) { uint8_t crc = 0; int32_t aux_index = 0; buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv for (size_t i = 0; i < buffer_index; ++i) { + // At most 2 more chars can be added in one loop iteration if (aux_index + 3 >= PACKET_BUFFER_AUX_SIZE) { // Too big for flush_batch. Fallback to traditional one-by-one send. bidib_flush_impl_old(); @@ -131,6 +142,7 @@ static void bidib_flush_impl(void) { //bidib_flush_batch_impl0 } } + // At most 3 more chars can be added in the code below if (aux_index + 4 >= PACKET_BUFFER_AUX_SIZE) { // Too big for flush batch, can't fit crc+delim in aux buffer. // Fallback to traditional one-by-one send. @@ -147,24 +159,18 @@ static void bidib_flush_impl(void) { //bidib_flush_batch_impl0 } buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv + // Batch-write aux buffer. write_bytes((uint8_t*)buffer_aux, aux_index); buffer_index = 0; } + syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); } void bidib_flush(void) { - //struct timespec start, end; pthread_mutex_lock(&bidib_send_buffer_mutex); - //bool smth_to_send = buffer_index > 0; - //clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_flush_impl(); - //clock_gettime(CLOCK_MONOTONIC_RAW, &end); pthread_mutex_unlock(&bidib_send_buffer_mutex); - //uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - //if (smth_to_send) { - // syslog_libbidib(LOG_WARNING, "Flush took %llu\n", delta_us); - //} } void *bidib_auto_flush(void *interval) { From 8702c37e91949d863a4b622ae88fa64e9aab2c52 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 27 Nov 2024 14:34:10 +0100 Subject: [PATCH 18/51] adjustments for debugging --- src/state/bidib_state_setter.c | 9 ++- src/transmission/bidib_transmission_receive.c | 14 +++-- test/physical/test_common.c | 57 ++++++++++++++++++- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 2baf7fb..015b890 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -435,6 +435,8 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); if (peripheral_mapping != NULL && (peripheral_state = bidib_state_get_peripheral_state_ref(peripheral_mapping->id->str)) != NULL) { + ///TODO: Does this cause a memory leak? maybe not, as it points to memory allocated for + // the aspect mapping probably. Is it assigned/malloc'd elsewhere? peripheral_state->data.state_id = NULL; t_bidib_aspect *aspect_mapping; for (size_t i = 0; i < peripheral_mapping->aspects->len; i++) { @@ -449,9 +451,10 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p "Aspect 0x%02x of peripheral %s is not mapped in config files", portstat, peripheral_mapping->id->str); } else { - syslog_libbidib(LOG_INFO, - "Feedback for action id %d: Peripheral: %s has aspect: %s (0x%02x)", - action_id, peripheral_mapping->id->str, aspect_mapping->id->str, portstat); + // Temporarily disabled for debugging (less logs to read) + //syslog_libbidib(LOG_INFO, + // "Feedback for action id %d: Peripheral: %s has aspect: %s (0x%02x)", + // action_id, peripheral_mapping->id->str, aspect_mapping->id->str, portstat); } peripheral_state->data.state_value = portstat; } else { diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index b28163d..f4fb476 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -418,8 +418,8 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, break; case MSG_LC_STAT: // update state - bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, - message, action_id); + //bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, + // message, action_id); peripheral_port.port0 = message[data_index]; peripheral_port.port1 = message[data_index + 1]; bidib_state_lc_stat(node_address, peripheral_port, message[data_index + 2], action_id); @@ -451,7 +451,8 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, break; case MSG_BM_FREE: // update state - bidib_log_received_message(addr_stack, seqnum, type, LOG_INFO, + ///TODO: keep at debug level or move back to info? + bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, message, action_id); bidib_state_bm_occ(node_address, message[data_index], false); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -730,6 +731,9 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) if (msg_read_in_us + node_update_us + handle_receive_us > slow_processing_threshold_us) { // In case the processing steps above take above the specified threshold, // i.e., longer than expected, log the time taken for each of the three steps. + syslog_libbidib(LOG_WARNING, + "bidib_split_packet took longer than threshold %llu us for message of type %s", + slow_processing_threshold_us, bidib_message_string_mapping[type]); syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us\n", msg_read_in_us); syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_us); syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us\n", handle_receive_us); @@ -781,7 +785,9 @@ static void bidib_receive_packet(void) { return; } - syslog_libbidib(LOG_DEBUG, "%s", "Received packet"); + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + syslog_libbidib(LOG_DEBUG, "Received packet, at time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); if (crc == 0x00) { // Split packet in messages and add them to queue, exclude crc sum diff --git a/test/physical/test_common.c b/test/physical/test_common.c index 8dfc27e..bfc4a6a 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -181,20 +181,73 @@ bool testsuite_trainReady(const char *train, const char *segment) { } } -void testsuite_driveTo(const char *segment, int speed, const char *train) { +void testsuite_driveTo_old(const char *segment, int speed, const char *train) { syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d", train, segment, speed); bidib_set_train_speed(train, speed, "master"); bidib_flush(); + long counter = 0; while (1) { t_bidib_train_position_query trainPosition = bidib_get_train_position(train); for (size_t i = 0; i < trainPosition.length; i++) { if (!strcmp(segment, trainPosition.segments[i])) { + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); bidib_free_train_position_query(trainPosition); - syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - REACHED TARGET", train, segment, speed); + syslog(LOG_WARNING, + "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", + train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } } bidib_free_train_position_query(trainPosition); + + if (counter++ % 4 == 0) { + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + syslog(LOG_WARNING, + "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", + train, segment, speed, tv.tv_sec, tv.tv_nsec); + } + + usleep(TRAIN_WAITING_TIME_US); + } +} + +void testsuite_driveTo(const char *segment, int speed, const char *train) { + // This driveTo impl works by querying the segment state repeatedly, not the train position. + // -> bidib_get_segment_state does not need to lock the trainstate rwlock, thus hopefully + // reducing lock contention. + syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d", train, segment, speed); + bidib_set_train_speed(train, speed, "master"); + bidib_flush(); + t_bidib_dcc_address_query tr_dcc_addr = bidib_get_train_dcc_addr(train); + t_bidib_dcc_address dcc_address; + long counter = 0; + while (1) { + t_bidib_segment_state_query seg_query = bidib_get_segment_state(segment); + for (size_t j = 0; j < seg_query.data.dcc_address_cnt; j++) { + dcc_address = seg_query.data.dcc_addresses[j]; + if (tr_dcc_addr.dcc_address.addrh == dcc_address.addrh + && tr_dcc_addr.dcc_address.addrl == dcc_address.addrl) { + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + bidib_free_segment_state_query(seg_query); + syslog(LOG_WARNING, + "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", + train, segment, speed, tv.tv_sec, tv.tv_nsec); + return; + } + } + bidib_free_segment_state_query(seg_query); + + if (counter++ % 4 == 0) { + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + syslog(LOG_WARNING, + "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", + train, segment, speed, tv.tv_sec, tv.tv_nsec); + } + usleep(TRAIN_WAITING_TIME_US); } } From 3f79d82448718c27763e82af940d42a4c964974b Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 27 Nov 2024 15:17:06 +0100 Subject: [PATCH 19/51] more debug stuff --- src/state/bidib_state_setter.c | 10 ++++++++++ test/physical/test_common.c | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 015b890..415e93b 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -859,7 +859,17 @@ void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t length, const uint8_t *const diag_list, unsigned int action_id) { + struct timespec start; + clock_gettime(CLOCK_MONOTONIC, &start); pthread_rwlock_wrlock(&bidib_state_track_rwlock); + struct timespec end; + clock_gettime(CLOCK_MONOTONIC, &end); + + uint64_t mut_acq_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + if (mut_acq_us > 100000 /*0.1s*/) { + syslog_libbidib(LOG_WARNING, "bidib_state_boost_diagnostic: took %lld us to acquire track lock", mut_acq_us); + } + t_bidib_booster_state *booster_state = bidib_state_get_booster_state_ref_by_nodeaddr(node_address); if (booster_state != NULL) { diff --git a/test/physical/test_common.c b/test/physical/test_common.c index bfc4a6a..da81599 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -218,6 +218,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { // -> bidib_get_segment_state does not need to lock the trainstate rwlock, thus hopefully // reducing lock contention. syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d", train, segment, speed); + printf("libbidib test: Drive %s to %s at speed %d\n", train, segment, speed); bidib_set_train_speed(train, speed, "master"); bidib_flush(); t_bidib_dcc_address_query tr_dcc_addr = bidib_get_train_dcc_addr(train); @@ -235,6 +236,8 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); + printf("libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", + train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } } @@ -246,6 +249,8 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); + printf("libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", + train, segment, speed, tv.tv_sec, tv.tv_nsec); } usleep(TRAIN_WAITING_TIME_US); From 48e3d7e5f84a8fea91599fd18a5c786838dccb1f Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Thu, 28 Nov 2024 16:09:38 +0100 Subject: [PATCH 20/51] rewrote trackstate access protection single lock to individ. mutexes --- src/highlevel/bidib_highlevel_getter.c | 206 ++++++++++++++---- src/highlevel/bidib_highlevel_intern.h | 22 +- src/highlevel/bidib_highlevel_setter.c | 141 +++++++++--- src/highlevel/bidib_highlevel_util.c | 53 ++++- src/lowlevel/bidib_lowlevel_intern.h | 5 +- src/lowlevel/bidib_lowlevel_track.c | 9 +- src/state/bidib_state.c | 182 ++++++++++++---- src/state/bidib_state_free.c | 3 +- src/state/bidib_state_getter.c | 13 +- src/state/bidib_state_getter_intern.h | 59 +++-- src/state/bidib_state_intern.h | 39 ++-- src/state/bidib_state_setter.c | 193 ++++++++++++---- src/state/bidib_state_setter_intern.h | 23 +- src/transmission/bidib_transmission_receive.c | 17 +- test/unit/bidib_highlevel_message_tests.c | 7 +- test/unit/bidib_parallel_tests.c | 9 +- 16 files changed, 760 insertions(+), 221 deletions(-) diff --git a/src/highlevel/bidib_highlevel_getter.c b/src/highlevel/bidib_highlevel_getter.c index 3559cc3..d875c97 100644 --- a/src/highlevel/bidib_highlevel_getter.c +++ b/src/highlevel/bidib_highlevel_getter.c @@ -78,6 +78,7 @@ static t_bidib_dcc_accessory_state *bidib_get_state_accessories_dcc(GArray *acce return state; } +// Shall only be called with trackstate_peripherals_mutex acquired static t_bidib_peripheral_state *bidib_get_state_peripherals(void) { t_bidib_peripheral_state *state = malloc( sizeof(t_bidib_peripheral_state) * bidib_track_state.peripherals->len); @@ -99,6 +100,7 @@ static t_bidib_peripheral_state *bidib_get_state_peripherals(void) { return state; } +// Shall only be called with trackstate_segments_mutex acquired static t_bidib_segment_state *bidib_get_state_segments(void) { t_bidib_segment_state *state = malloc( sizeof(t_bidib_segment_state) * bidib_track_state.segments->len); @@ -118,6 +120,7 @@ static t_bidib_segment_state *bidib_get_state_segments(void) { return state; } +// Shall only be called with trackstate_reversers_mutex acquired static t_bidib_reverser_state *bidib_get_state_reversers(void) { t_bidib_reverser_state *state = malloc( sizeof(t_bidib_reverser_state) * bidib_track_state.reversers->len); @@ -139,6 +142,7 @@ static t_bidib_reverser_state *bidib_get_state_reversers(void) { return state; } +// Shall only be called with trackstate_trains_mutex acquired static t_bidib_train_state *bidib_get_state_trains(void) { t_bidib_train_state *state = malloc(sizeof(t_bidib_train_state)*bidib_track_state.trains->len); for (size_t i = 0; i < bidib_track_state.trains->len; i++) { @@ -169,6 +173,7 @@ static t_bidib_train_state *bidib_get_state_trains(void) { return state; } +// Shall only be called with trackstate_boosters_mutex acquired static t_bidib_booster_state *bidib_get_state_boosters(void) { t_bidib_booster_state *state = malloc( sizeof(t_bidib_booster_state) * bidib_track_state.boosters->len); @@ -187,6 +192,7 @@ static t_bidib_booster_state *bidib_get_state_boosters(void) { return state; } +// Shall only be called with trackstate_track_outputs_mutex acquired static t_bidib_track_output_state *bidib_get_state_track_outputs(void) { t_bidib_track_output_state *state = malloc( sizeof(t_bidib_track_output_state) * bidib_track_state.track_outputs->len); @@ -203,7 +209,9 @@ static t_bidib_track_output_state *bidib_get_state_track_outputs(void) { t_bidib_track_state bidib_get_state(void) { t_bidib_track_state query = {0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL}; - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.points_board, .points_dcc, .signals_board, .signals_dcc + pthread_mutex_lock(&trackstate_accessories_mutex); query.points_board_count = bidib_track_state.points_board->len; query.points_board = bidib_get_state_accessories_board(bidib_track_state.points_board); query.points_dcc_count = bidib_track_state.points_dcc->len; @@ -212,19 +220,45 @@ t_bidib_track_state bidib_get_state(void) { query.signals_board = bidib_get_state_accessories_board(bidib_track_state.signals_board); query.signals_dcc_count = bidib_track_state.signals_dcc->len; query.signals_dcc = bidib_get_state_accessories_dcc(bidib_track_state.signals_dcc); + pthread_mutex_unlock(&trackstate_accessories_mutex); + + // For accessing bidib_track_state.peripherals, for bidib_get_state_peripherals + pthread_mutex_lock(&trackstate_peripherals_mutex); query.peripherals_count = bidib_track_state.peripherals->len; query.peripherals = bidib_get_state_peripherals(); + pthread_mutex_unlock(&trackstate_peripherals_mutex); + + // For accessing bidib_track_state.segments, for bidib_get_state_segments + pthread_mutex_lock(&trackstate_segments_mutex); query.segments_count = bidib_track_state.segments->len; query.segments = bidib_get_state_segments(); + pthread_mutex_unlock(&trackstate_segments_mutex); + + // For accessing bidib_track_state.reversers, for bidib_get_state_reversers + pthread_mutex_lock(&trackstate_reversers_mutex); query.reversers_count = bidib_track_state.reversers->len; query.reversers = bidib_get_state_reversers(); + pthread_mutex_unlock(&trackstate_reversers_mutex); + + // For accessing bidib_track_state.trains, for bidib_get_state_trains + pthread_mutex_lock(&trackstate_trains_mutex); query.trains_count = bidib_track_state.trains->len; query.trains = bidib_get_state_trains(); + pthread_mutex_unlock(&trackstate_trains_mutex); + + // For accessing bidib_track_state.boosters, for bidib_get_state_boosters + pthread_mutex_lock(&trackstate_boosters_mutex); query.booster_count = bidib_track_state.boosters->len; query.booster = bidib_get_state_boosters(); + pthread_mutex_unlock(&trackstate_boosters_mutex); + + // For accessing bidib_track_state.track_outputs, for bidib_get_state_track_outputs + pthread_mutex_lock(&trackstate_track_outputs_mutex); query.track_outputs_count = bidib_track_state.track_outputs->len; query.track_outputs = bidib_get_state_track_outputs(); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_track_outputs_mutex); + + //pthread_rwlock_unlock(&bidib_state_track_rwlock); return query; } @@ -714,7 +748,9 @@ t_bidib_id_list_query bidib_get_connected_boosters(void) { t_bidib_id_list_query bidib_get_boosters(void) { t_bidib_id_list_query query = {0, NULL}; - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.boosters + pthread_mutex_lock(&trackstate_boosters_mutex); if (bidib_track_state.boosters->len > 0) { query.length = bidib_track_state.boosters->len; query.ids = malloc(sizeof(char *) * query.length); @@ -725,7 +761,8 @@ t_bidib_id_list_query bidib_get_boosters(void) { strcpy(query.ids[i], state_i.id); } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_boosters_mutex); return query; } @@ -759,7 +796,10 @@ t_bidib_id_list_query bidib_get_connected_track_outputs(void) { t_bidib_id_list_query bidib_get_track_outputs(void) { t_bidib_id_list_query query = {0, NULL}; - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.track_outputs + pthread_mutex_lock(&trackstate_track_outputs_mutex); + if (bidib_track_state.track_outputs->len > 0) { query.length = bidib_track_state.track_outputs->len; query.ids = malloc(sizeof(char *) * query.length); @@ -771,49 +811,63 @@ t_bidib_id_list_query bidib_get_track_outputs(void) { strcpy(query.ids[i], state_i.id); } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_track_outputs_mutex); return query; } size_t bidib_get_point_state_index(const char *point) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.points_board + pthread_mutex_lock(&trackstate_accessories_mutex); for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { const t_bidib_board_accessory_state *const accessory_state = &g_array_index( bidib_track_state.points_board, t_bidib_board_accessory_state, i); - if (!strcmp(accessory_state->id, point)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + if (strcmp(accessory_state->id, point) == 0) { + pthread_mutex_unlock(&trackstate_accessories_mutex); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); return i; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); return -1; } size_t bidib_get_signal_state_index(const char *signal) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.signals_board + pthread_mutex_lock(&trackstate_accessories_mutex); + for (size_t i = 0; i < bidib_track_state.signals_board->len; i++) { const t_bidib_board_accessory_state *const accessory_state = &g_array_index( bidib_track_state.signals_board, t_bidib_board_accessory_state, i); - if (!strcmp(accessory_state->id, signal)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + if (strcmp(accessory_state->id, signal) == 0) { + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return i; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return -1; } size_t bidib_get_segment_state_index(const char *segment) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.segments + pthread_mutex_lock(&trackstate_segments_mutex); for (size_t i = 0; i < bidib_track_state.segments->len; i++) { const t_bidib_segment_state_intern *const segment_state_i = &g_array_index( bidib_track_state.segments, t_bidib_segment_state_intern, i); if (!strcmp(segment_state_i->id->str, segment)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); return i; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); return -1; } @@ -822,7 +876,12 @@ t_bidib_unified_accessory_state_query bidib_get_point_state(const char *point) { if (point == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + + // For bidib_state_get_board_accessory_state_ref and bidib_state_get_dcc_accessory_state_ref + pthread_mutex_lock(&trackstate_accessories_mutex); + const t_bidib_board_accessory_state *const board_accessory_tmp = bidib_state_get_board_accessory_state_ref(point, true); if (board_accessory_tmp != NULL) { @@ -859,7 +918,8 @@ t_bidib_unified_accessory_state_query bidib_get_point_state(const char *point) { query.dcc_accessory_state.switch_time = dcc_tmp->data.switch_time; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return query; } @@ -868,7 +928,10 @@ t_bidib_unified_accessory_state_query bidib_get_signal_state(const char *signal) if (signal == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_board_accessory_state_ref and bidib_state_get_dcc_accessory_state_ref + pthread_mutex_lock(&trackstate_accessories_mutex); + const t_bidib_board_accessory_state *const board_accessory_tmp = bidib_state_get_board_accessory_state_ref(signal, false); if (board_accessory_tmp != NULL) { @@ -904,7 +967,8 @@ t_bidib_unified_accessory_state_query bidib_get_signal_state(const char *signal) query.dcc_accessory_state.switch_time = dcc_tmp->data.switch_time; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return query; } @@ -914,7 +978,10 @@ t_bidib_peripheral_state_query bidib_get_peripheral_state(const char *peripheral if (peripheral == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_peripheral_state_ref + pthread_mutex_lock(&trackstate_peripherals_mutex); + const t_bidib_peripheral_state *const tmp = bidib_state_get_peripheral_state_ref(peripheral); if (tmp != NULL) { query.available = true; @@ -930,7 +997,8 @@ t_bidib_peripheral_state_query bidib_get_peripheral_state(const char *peripheral query.data.time_unit = tmp->data.time_unit; query.data.wait = tmp->data.wait; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_peripherals_mutex); return query; } @@ -941,7 +1009,10 @@ t_bidib_segment_state_query bidib_get_segment_state(const char *segment) { if (segment == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_segment_state_ref + pthread_mutex_lock(&trackstate_segments_mutex); + const t_bidib_segment_state_intern *const tmp = bidib_state_get_segment_state_ref(segment); if (tmp != NULL) { query.known = true; @@ -954,7 +1025,8 @@ t_bidib_segment_state_query bidib_get_segment_state(const char *segment) { memcpy(query.data.dcc_addresses, tmp->dcc_addresses->data, sizeof(t_bidib_dcc_address) * tmp->dcc_addresses->len); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); return query; } @@ -964,7 +1036,10 @@ t_bidib_reverser_state_query bidib_get_reverser_state(const char *reverser) { if (reverser == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_reverser_state_ref + pthread_mutex_lock(&trackstate_reversers_mutex); + const t_bidib_reverser_state *const tmp = bidib_state_get_reverser_state_ref(reverser); if (tmp != NULL) { query.available = true; @@ -978,7 +1053,7 @@ t_bidib_reverser_state_query bidib_get_reverser_state(const char *reverser) { strcpy(query.data.state_id, state_id); query.data.state_value = tmp->data.state_value; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); return query; } @@ -988,7 +1063,10 @@ t_bidib_booster_state_query bidib_get_booster_state(const char *booster) { if (booster == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_booster_state_ref + pthread_mutex_lock(&trackstate_boosters_mutex); + const t_bidib_booster_state *const tmp = bidib_state_get_booster_state_ref(booster); if (tmp != NULL) { query.known = true; @@ -1000,7 +1078,8 @@ t_bidib_booster_state_query bidib_get_booster_state(const char *booster) { query.data.temp_known = tmp->data.temp_known; query.data.temp_celsius = tmp->data.temp_celsius; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_boosters_mutex); return query; } @@ -1010,14 +1089,17 @@ t_bidib_track_output_state_query bidib_get_track_output_state(const char *track_ if (track_output == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_track_output_state_ref + pthread_mutex_lock(&trackstate_track_outputs_mutex); const t_bidib_track_output_state *const tmp = bidib_state_get_track_output_state_ref(track_output); if (tmp != NULL) { query.known = true; query.cs_state = tmp->cs_state; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_track_outputs_mutex); return query; } @@ -1040,7 +1122,10 @@ t_bidib_id_list_query bidib_get_trains(void) { t_bidib_id_list_query bidib_get_trains_on_track(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.trains + pthread_mutex_lock(&trackstate_trains_mutex); + for (size_t i = 0; i < bidib_track_state.trains->len; i++) { const t_bidib_train_state_intern *const train_state_tmp = &g_array_index(bidib_track_state.trains, t_bidib_train_state_intern, i); @@ -1062,7 +1147,8 @@ t_bidib_id_list_query bidib_get_trains_on_track(void) { } } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1129,7 +1215,10 @@ t_bidib_train_state_query bidib_get_train_state(const char *train) { if (train == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); + const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); if (train_state != NULL) { query.known = true; @@ -1152,7 +1241,8 @@ t_bidib_train_state_query bidib_get_train_state(const char *train) { } query.data.decoder_state = train_state->decoder_state; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1162,7 +1252,10 @@ t_bidib_train_peripheral_state_query bidib_get_train_peripheral_state(const char if (train == NULL || peripheral == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); + const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); if (train_state != NULL) { for (size_t i = 0; i < train_state->peripherals->len; i++) { @@ -1175,7 +1268,8 @@ t_bidib_train_peripheral_state_query bidib_get_train_peripheral_state(const char } } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1184,12 +1278,16 @@ bool bidib_get_train_on_track(const char *train) { if (train == NULL) { return res; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); + const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); if (train_state != NULL && train_state->on_track) { res = true; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); return res; } @@ -1198,6 +1296,11 @@ t_bidib_train_position_query bidib_get_train_position_intern(const char *train) if (train == NULL) { return query; } + // Notes regarding mutexes/locks: + // - bidib_state_get_train_state_ref: trackstate_trains_mutex + // - access bidib_track_state.segments: trackstate_segments_mutex + // - bidib_state_get_train_ref: bidib_state_trains_rwlock >= read + const t_bidib_train_state_intern *const train_state_ref = bidib_state_get_train_state_ref(train); const t_bidib_train *const train_ref = bidib_state_get_train_ref(train); if (train_state_ref != NULL && train_ref != NULL) { @@ -1240,10 +1343,17 @@ t_bidib_train_position_query bidib_get_train_position_intern(const char *train) } t_bidib_train_position_query bidib_get_train_position(const char *train) { + // All for bidib_get_train_position_intern pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + pthread_mutex_lock(&trackstate_segments_mutex); + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_train_position_query query = bidib_get_train_position_intern(train); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); + pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); return query; @@ -1254,14 +1364,17 @@ t_bidib_train_speed_step_query bidib_get_train_speed_step(const char *train) { if (train == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); if (train_state != NULL && train_state->on_track) { query.known_and_avail = true; query.speed_step = train_state->set_speed_step; query.is_forwards = train_state->set_is_forwards; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1270,13 +1383,16 @@ t_bidib_train_speed_kmh_query bidib_get_train_speed_kmh(const char *train) { if (train == NULL) { return query; } - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); if (train_state != NULL && train_state->on_track) { query.known_and_avail = true; query.speed_kmh = train_state->detected_kmh_speed; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); return query; } diff --git a/src/highlevel/bidib_highlevel_intern.h b/src/highlevel/bidib_highlevel_intern.h index ea164a3..f723984 100644 --- a/src/highlevel/bidib_highlevel_intern.h +++ b/src/highlevel/bidib_highlevel_intern.h @@ -36,10 +36,18 @@ extern pthread_rwlock_t bidib_state_trains_rwlock; -extern pthread_rwlock_t bidib_state_track_rwlock; +//extern pthread_rwlock_t bidib_state_track_rwlock; extern pthread_rwlock_t bidib_state_boards_rwlock; extern pthread_mutex_t bidib_action_id_mutex; +extern pthread_mutex_t trackstate_accessories_mutex; +extern pthread_mutex_t trackstate_peripherals_mutex; +extern pthread_mutex_t trackstate_segments_mutex; +extern pthread_mutex_t trackstate_reversers_mutex; +extern pthread_mutex_t trackstate_trains_mutex; +extern pthread_mutex_t trackstate_boosters_mutex; +extern pthread_mutex_t trackstate_track_outputs_mutex; + /** * Returns the next action id and increments it afterwards. * @@ -50,11 +58,23 @@ unsigned int bidib_get_and_incr_action_id(void); /** * Used only internally in bidib_state_update_train_available and * bidib_get_train_position to avoid the usage of a recursive mutex. + * + * Shall only be called with with bidib_state_trains_rwlock >= read acquired, + * and with trackstate_segments_mutex and trackstate_trains_mutex acquired. * * @param train the id of the train. * @return the train position. Must be freed by the caller. */ t_bidib_train_position_query bidib_get_train_position_intern(const char *train); +/** + * To be run in separate thread; when bidib is running, + * prints a heartbeat message with a timestep in + * a 2-second interval. + * + * @param __attribute__ unused + * @return void* + */ +void *bidib_heartbeat_log(void *par __attribute__((unused))); #endif diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index 3ccc362..e804319 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -71,8 +71,14 @@ int bidib_switch_point(const char *point, const char *aspect) { return 1; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_send_cs_accessory_intern and bidib_state_get_dcc_accessory_state_ref + pthread_mutex_lock(&trackstate_accessories_mutex); + + // For accessing bidib_boards and bidib_send_cs_accessory_intern pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + + for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); @@ -85,7 +91,8 @@ int bidib_switch_point(const char *point, const char *aspect) { syslog_libbidib(LOG_ERR, "Switch point %s: board %s is not connected", point, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -108,7 +115,8 @@ int bidib_switch_point(const char *point, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } } @@ -122,7 +130,8 @@ int bidib_switch_point(const char *point, const char *aspect) { syslog_libbidib(LOG_ERR, "Switch point %s: board %s is not connected", point, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } t_bidib_node_address tmp_addr = board_i->node_addr; @@ -164,11 +173,13 @@ int bidib_switch_point(const char *point, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } else { pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Switch point %s: aspect %s doesn't exist", point, aspect); return 1; @@ -177,7 +188,8 @@ int bidib_switch_point(const char *point, const char *aspect) { } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Switch point %s: not found", point); return 1; } @@ -188,7 +200,11 @@ int bidib_set_signal(const char *signal, const char *aspect) { return 1; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_send_cs_accessory_intern and bidib_state_get_dcc_accessory_state_ref + pthread_mutex_lock(&trackstate_accessories_mutex); + + // For accessing bidib_boards and bidib_send_cs_accessory_intern pthread_rwlock_rdlock(&bidib_state_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { @@ -201,7 +217,8 @@ int bidib_set_signal(const char *signal, const char *aspect) { syslog_libbidib(LOG_ERR, "Set signal %s: board %s is not connected", signal, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } t_bidib_node_address tmp_addr = board_i->node_addr; @@ -223,7 +240,8 @@ int bidib_set_signal(const char *signal, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } } @@ -236,7 +254,8 @@ int bidib_set_signal(const char *signal, const char *aspect) { syslog_libbidib(LOG_ERR, "Set signal %s: board %s is not connected", signal, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } t_bidib_node_address tmp_addr = board_i->node_addr; @@ -280,13 +299,15 @@ int bidib_set_signal(const char *signal, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Set signal %s: not found", signal); return 1; } @@ -336,6 +357,15 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { return 1; } +/** + * Set the train speed on track output to some value. + * Shall only be called with bidib_state_trains_rwlock >=read acquired. + * + * @param train the id/name of the train whose speed to set + * @param speed the speed to set + * @param track_output for which track output shall the speed of the train be set? + * @return int 0 if successful, 1 otherwise. + */ int bidib_set_train_speed_internal(const char *train, int speed, const char *track_output){ if (train == NULL || track_output == NULL) { syslog_libbidib(LOG_ERR, "Set train speed: parameters must not be NULL"); @@ -347,20 +377,34 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra speed); return 1; } + // Notes regarding mutexes/locks: + // - bidib_state_get_train_ref: bidib_state_trains_rwlock >=read -> by caller + // - bidib_state_get_board_ref: bidib_state_boards_rwlock >=read -> locked locally + // - bidib_state_get_train_state_ref: trackstate_trains_mutex -> locked locally + // - bidib_send_cs_drive_intern: we pass false -> need lock bidib_state_trains_rwlock -> caller + // Important: trackstate_trains_mutex and bidib_state_boards_rwlock have to be released + // before bidib_send_cs_drive_intern is called. + const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (tmp_train == NULL) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); syslog_libbidib(LOG_ERR, "Set train speed: train %s doesn't exist", train); return 1; } else if (board == NULL || !board->connected) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); syslog_libbidib(LOG_ERR, "Set train speed: board %s doesn't exist or is not connected", track_output); return 1; } else if (!(board->unique_id.class_id & (1 << 4))) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); syslog_libbidib(LOG_ERR, "Set train speed: board %s has no track output", track_output); return 1; @@ -369,7 +413,7 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra bool is_forwards = (speed > 0); if (speed == 0) { // Preserve the orientation of the train headlights - t_bidib_train_state_intern *tmp_train_state = bidib_state_get_train_state_ref(train); + const t_bidib_train_state_intern *tmp_train_state = bidib_state_get_train_state_ref(train); is_forwards = tmp_train_state->set_is_forwards; } @@ -400,6 +444,8 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra board->node_addr.sub, board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = board->node_addr; pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); + bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); return 0; } @@ -515,19 +561,37 @@ int bidib_emergency_stop_train(const char *train, const char *track_output) { // Must be called with bidib_state_trains_rwlock >=read acquired and // bidib_state_track_rwlock >=read acquired. + +/** + * Get the current bit(s) for the train peripherals. + * Shall only be called with trackstate_trains_mutex acquired; + * And if the passed "train" param is a part of bidib_trains, + * which is very likely, then bidib_state_trains_rwlock >= read has to be acquired too. + * + * @param train + * @param start + * @param end + * @param bits (out-parameter) + */ static void bidib_get_current_train_peripheral_bits(const t_bidib_train *const train, size_t start, size_t end, uint8_t *bits) { - const t_bidib_train_state_intern * train_state = + const t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref(train->id->str); for (size_t i = 0; i < train->peripherals->len; i++) { const t_bidib_train_peripheral_mapping *const mapping_i = &g_array_index(train->peripherals, t_bidib_train_peripheral_mapping, i); if (mapping_i->bit >= start && mapping_i->bit <= end) { + ///NOTE: j is actually not used in the nested loop, is that intentional? + ///TODO: Test. + const t_bidib_train_peripheral_state *const train_per_state_i = + bidib_state_get_train_peripheral_state_by_bit(train_state, mapping_i->bit); + *bits |= (train_per_state_i->state << (mapping_i->bit % 8)); + /* for (size_t j = 0; j < train->peripherals->len; j++) { const t_bidib_train_peripheral_state *const train_per_state_i = bidib_state_get_train_peripheral_state_by_bit(train_state, mapping_i->bit); *bits |= (train_per_state_i->state << (mapping_i->bit % 8)); - } + }*/ } } } @@ -538,10 +602,22 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ syslog_libbidib(LOG_ERR, "Set train peripheral: parameters must not be NULL"); return 1; } + // Notes on mutexes/locks: + // - bidib_state_get_train_ref: bidib_state_trains_rwlock >=read + // - bidib_state_get_board_ref: bidib_state_boards_rwlock >=read + // - bidib_get_current_train_peripheral_bits: trackstate_trains_mutex (and techn. trains_wrlock) + // - bidib_send_cs_drive_intern: bidib_state_trains_rwlock >=read (as we pass false for lock param) + + // For bidib_state_get_train_ref and bidib_send_cs_drive_intern pthread_rwlock_wrlock(&bidib_state_trains_rwlock); - const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For bidib_get_current_train_peripheral_bits + pthread_mutex_lock(&trackstate_trains_mutex); + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + + const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (tmp_train == NULL || board == NULL @@ -556,7 +632,8 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ track_output); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); return 1; } @@ -564,7 +641,7 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ for (size_t i = 0; i < tmp_train->peripherals->len; i++) { const t_bidib_train_peripheral_mapping *const mapping_i = &g_array_index( tmp_train->peripherals, t_bidib_train_peripheral_mapping, i); - if (!strcmp(peripheral, mapping_i->id->str)) { + if (strcmp(peripheral, mapping_i->id->str) == 0) { t_bidib_cs_drive_mod params; params.dcc_address = tmp_train->dcc_addr; switch (tmp_train->dcc_speed_steps) { @@ -616,14 +693,16 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ board->node_addr.sub, board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = board->node_addr; pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); pthread_rwlock_unlock(&bidib_state_trains_rwlock); return 0; } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); syslog_libbidib(LOG_ERR, "Set train peripheral: peripheral %s doesn't exist", peripheral); return 1; @@ -719,22 +798,27 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { return 1; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_reverser_state_ref + pthread_mutex_lock(&trackstate_reversers_mutex); + // For bidib_state_get_board_ref and bidib_state_get_reverser_mapping_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); - t_bidib_board *board_ref = bidib_state_get_board_ref(board); - t_bidib_reverser_mapping *mapping_ref = bidib_state_get_reverser_mapping_ref(reverser); + const t_bidib_board *board_ref = bidib_state_get_board_ref(board); + const t_bidib_reverser_mapping *mapping_ref = bidib_state_get_reverser_mapping_ref(reverser); t_bidib_reverser_state *state_ref = bidib_state_get_reverser_state_ref(reverser); if (board_ref == NULL || !board_ref->connected) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Request reverser state: board %s doesn't exist or is not connected", board); return 1; } else if (mapping_ref == NULL || state_ref == NULL) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Request reverser state: reverser %s does not exist", board); @@ -750,6 +834,7 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { (uint8_t *)mapping_ref->cv->str, 0); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); return 0; } diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index c2eeee9..669f5af 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "../../include/highlevel/bidib_highlevel_util.h" #include "../../include/highlevel/bidib_highlevel_setter.h" @@ -45,15 +46,24 @@ static pthread_t bidib_receiver_thread = 0; static pthread_t bidib_autoflush_thread = 0; +static pthread_t bidib_heartbeat_thread = 0; // Pthread locks that protect read/write access to the bidib_boards, // bidib_track_state, bidib_trains data structures. // They do NOT protect the concurrent sending of low-level commands // to the BiDiB master node over a serial connection. pthread_rwlock_t bidib_state_trains_rwlock; -pthread_rwlock_t bidib_state_track_rwlock; +//pthread_rwlock_t bidib_state_track_rwlock; pthread_rwlock_t bidib_state_boards_rwlock; +pthread_mutex_t trackstate_accessories_mutex; +pthread_mutex_t trackstate_peripherals_mutex; +pthread_mutex_t trackstate_segments_mutex; +pthread_mutex_t trackstate_reversers_mutex; +pthread_mutex_t trackstate_trains_mutex; +pthread_mutex_t trackstate_boosters_mutex; +pthread_mutex_t trackstate_track_outputs_mutex; + volatile bool bidib_running = false; volatile bool bidib_discard_rx = true; @@ -61,11 +71,39 @@ volatile bool bidib_lowlevel_debug_mode = false; static void bidib_init_rwlocks(void) { pthread_rwlock_init(&bidib_state_trains_rwlock, NULL); - pthread_rwlock_init(&bidib_state_track_rwlock, NULL); + //pthread_rwlock_init(&bidib_state_track_rwlock, NULL); pthread_rwlock_init(&bidib_state_boards_rwlock, NULL); } static void bidib_init_mutexes(void) { + // New fine grained mutexes for trackstate + pthread_mutex_init(&trackstate_accessories_mutex, NULL); + pthread_mutex_init(&trackstate_peripherals_mutex, NULL); + pthread_mutex_init(&trackstate_segments_mutex, NULL); + pthread_mutex_init(&trackstate_reversers_mutex, NULL); + pthread_mutex_init(&trackstate_trains_mutex, NULL); + pthread_mutex_init(&trackstate_boosters_mutex, NULL); + pthread_mutex_init(&trackstate_track_outputs_mutex, NULL); + + + pthread_mutex_lock(&trackstate_accessories_mutex); + pthread_mutex_lock(&trackstate_peripherals_mutex); + pthread_mutex_lock(&trackstate_segments_mutex); + pthread_mutex_lock(&trackstate_reversers_mutex); + pthread_mutex_lock(&trackstate_trains_mutex); + pthread_mutex_lock(&trackstate_boosters_mutex); + pthread_mutex_lock(&trackstate_track_outputs_mutex); + + pthread_mutex_unlock(&trackstate_track_outputs_mutex); + pthread_mutex_unlock(&trackstate_boosters_mutex); + pthread_mutex_unlock(&trackstate_trains_mutex); + pthread_mutex_unlock(&trackstate_reversers_mutex); + pthread_mutex_unlock(&trackstate_segments_mutex); + pthread_mutex_unlock(&trackstate_peripherals_mutex); + pthread_mutex_unlock(&trackstate_accessories_mutex); + + // End of new fine grained mutexes for trackstate initialization + pthread_mutex_init(&bidib_node_state_table_mutex, NULL); pthread_mutex_init(&bidib_send_buffer_mutex, NULL); pthread_mutex_init(&bidib_uplink_queue_mutex, NULL); @@ -90,6 +128,7 @@ static void bidib_init_mutexes(void) { static void bidib_init_threads(unsigned int flush_interval) { pthread_create(&bidib_receiver_thread, NULL, bidib_auto_receive, NULL); + pthread_create(&bidib_heartbeat_thread, NULL, bidib_heartbeat_log, NULL); if (flush_interval > 0) { unsigned int *arg = malloc(sizeof(unsigned int)); *arg = flush_interval; @@ -227,3 +266,13 @@ void syslog_libbidib(int priority, const char *format, ...) { vsnprintf(string, 1024, format, arg); syslog(priority, "libbidib: %s", string); } + +void *bidib_heartbeat_log(void *par __attribute__((unused))) { + while (bidib_running) { + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + syslog_libbidib(LOG_DEBUG, "Heartbeat, time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); + sleep(2); + } + return NULL; +} \ No newline at end of file diff --git a/src/lowlevel/bidib_lowlevel_intern.h b/src/lowlevel/bidib_lowlevel_intern.h index 9f8fdd0..cf42816 100644 --- a/src/lowlevel/bidib_lowlevel_intern.h +++ b/src/lowlevel/bidib_lowlevel_intern.h @@ -53,7 +53,10 @@ void bidib_send_cs_drive_intern(t_bidib_node_address node_address, /** * Issues an accessory command. - * Must only be called with bidib_state_track_rwlock write acquired, + * Shall only be called with trackstate_accessories_mutex acquired, + * and with bidib_state_boards_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock write acquired, * and with bidib_state_boards_rwlock >=read acquired. * * @param node_address the three bytes on top of the address stack. diff --git a/src/lowlevel/bidib_lowlevel_track.c b/src/lowlevel/bidib_lowlevel_track.c index b7a824f..4f8b03b 100644 --- a/src/lowlevel/bidib_lowlevel_track.c +++ b/src/lowlevel/bidib_lowlevel_track.c @@ -112,11 +112,16 @@ void bidib_send_cs_accessory_intern(t_bidib_node_address node_address, void bidib_send_cs_accessory(t_bidib_node_address node_address, t_bidib_cs_accessory_mod cs_accessory_params, unsigned int action_id) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // Both for bidib_send_cs_accessory_intern + pthread_mutex_lock(&trackstate_accessories_mutex); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + bidib_send_cs_accessory_intern(node_address, cs_accessory_params, action_id); + pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); } void bidib_send_cs_pom(t_bidib_node_address node_address, diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 1a31c00..05dc6ec 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -322,13 +322,19 @@ void bidib_state_set_initial_values(void) { for (size_t i = 0; i < bidib_initial_values.trains->len; i++) { train_initial_value = &g_array_index( bidib_initial_values.trains, t_bidib_state_train_initial_value, i); + ///NOTE: Technically, we need to protect this access of bidib_track_state.track_outputs + // with trackstate_track_outputs_mutex, but due to what is being called in the loop body, + // this is not really possible if we want to keep the lock ordering consistent. + // At least not without significantly complicating a lot of the locking. for (size_t j = 0; j < bidib_track_state.track_outputs->len; j++) { track_output_state = &g_array_index( bidib_track_state.track_outputs, t_bidib_track_output_state, j); - bidib_set_train_peripheral(train_initial_value->train->str, - train_initial_value->id->str, train_initial_value->value, - track_output_state->id); - bidib_set_train_speed(train_initial_value->train->str, 0, track_output_state->id); + if (track_output_state != NULL) { + bidib_set_train_peripheral(train_initial_value->train->str, + train_initial_value->id->str, train_initial_value->value, + track_output_state->id); + bidib_set_train_speed(train_initial_value->train->str, 0, track_output_state->id); + } } } bidib_flush(); @@ -466,111 +472,149 @@ bool bidib_state_add_train(t_bidib_train train) { } static bool bidib_state_point_exists(const char *id) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.points_board and .points_dcc + pthread_mutex_lock(&trackstate_accessories_mutex); for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.points_board, t_bidib_board_accessory_state, i).id)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } } for (size_t i = 0; i < bidib_track_state.points_dcc->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.points_dcc, t_bidib_dcc_accessory_state, i).id)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } static bool bidib_state_signal_exists(const char *id) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.signals_board, .signals_dcc + pthread_mutex_lock(&trackstate_accessories_mutex); for (size_t i = 0; i < bidib_track_state.signals_board->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.signals_board, t_bidib_board_accessory_state, i).id)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } } for (size_t i = 0; i < bidib_track_state.signals_dcc->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.signals_dcc, t_bidib_dcc_accessory_state, i).id)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } static bool bidib_state_peripheral_exists(const char *id) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.peripherals + pthread_mutex_lock(&trackstate_peripherals_mutex); + for (size_t i = 0; i < bidib_track_state.peripherals->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.peripherals, t_bidib_peripheral_state, i).id)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_peripherals_mutex); return true; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_peripherals_mutex); return false; } static bool bidib_state_segment_exists(const char *id) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.segments + pthread_mutex_lock(&trackstate_segments_mutex); for (size_t i = 0; i < bidib_track_state.segments->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.segments, t_bidib_segment_state_intern, i).id->str)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); return true; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); return false; } static bool bidib_state_reverser_exists(const char *id) { - pthread_rwlock_rdlock(&bidib_state_track_rwlock); + //pthread_rwlock_rdlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.reversers + pthread_mutex_lock(&trackstate_reversers_mutex); + for (size_t i = 0; i < bidib_track_state.reversers->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.reversers, t_bidib_reverser_state, i).id)) { - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); return true; } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); return false; } void bidib_state_add_booster(t_bidib_booster_state booster_state) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.boosters + pthread_mutex_lock(&trackstate_boosters_mutex); g_array_append_val(bidib_track_state.boosters, booster_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_boosters_mutex); } void bidib_state_add_track_output(t_bidib_track_output_state track_output_state) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.track_outputs + pthread_mutex_lock(&trackstate_track_outputs_mutex); g_array_append_val(bidib_track_state.track_outputs, track_output_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_track_outputs_mutex); } void bidib_state_add_train_state(t_bidib_train_state_intern train_state) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref and for accessing bidib_track_state.trains + pthread_mutex_lock(&trackstate_trains_mutex); + if (bidib_state_get_train_state_ref(train_state.id->str) == NULL) { g_array_append_val(bidib_track_state.trains, train_state); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); } bool bidib_state_add_board_point_state(t_bidib_board_accessory_state point_state) { if (bidib_state_point_exists(point_state.id)) { return true; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.points_board + pthread_mutex_lock(&trackstate_accessories_mutex); + g_array_append_val(bidib_track_state.points_board, point_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -578,9 +622,13 @@ bool bidib_state_add_board_signal_state(t_bidib_board_accessory_state signal_sta if (bidib_state_signal_exists(signal_state.id)) { return true; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.signals_board + pthread_mutex_lock(&trackstate_accessories_mutex); + g_array_append_val(bidib_track_state.signals_board, signal_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -592,9 +640,14 @@ bool bidib_state_add_dcc_point_state(t_bidib_dcc_accessory_state point_state, return true; } pthread_rwlock_unlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.points_dcc + pthread_mutex_lock(&trackstate_accessories_mutex); + g_array_append_val(bidib_track_state.points_dcc, point_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -606,9 +659,14 @@ bool bidib_state_add_dcc_signal_state(t_bidib_dcc_accessory_state signal_state, return true; } pthread_rwlock_unlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.signals_dcc + pthread_mutex_lock(&trackstate_accessories_mutex); + g_array_append_val(bidib_track_state.signals_dcc, signal_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -616,9 +674,13 @@ bool bidib_state_add_peripheral_state(t_bidib_peripheral_state peripheral_state) if (bidib_state_peripheral_exists(peripheral_state.id)) { return true; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.peripherals + pthread_mutex_lock(&trackstate_peripherals_mutex); + g_array_append_val(bidib_track_state.peripherals, peripheral_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_peripherals_mutex); return false; } @@ -626,9 +688,13 @@ bool bidib_state_add_segment_state(t_bidib_segment_state_intern segment_state) { if (bidib_state_segment_exists(segment_state.id->str)) { return true; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.segments + pthread_mutex_lock(&trackstate_segments_mutex); + g_array_append_val(bidib_track_state.segments, segment_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); return false; } @@ -636,9 +702,13 @@ bool bidib_state_add_reverser_state(t_bidib_reverser_state reverser_state) { if (bidib_state_reverser_exists(reverser_state.id)) { return true; } - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.reversers + pthread_mutex_lock(&trackstate_reversers_mutex); + g_array_append_val(bidib_track_state.reversers, reverser_state); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); return false; } @@ -659,6 +729,10 @@ void bidib_state_add_initial_train_value(t_bidib_state_train_initial_value value } void bidib_state_update_train_available(void) { + // Notes regarding mutexes/locks: + // - accessing bidib_track_state.trains: trackstate_trains_mutex + // - bidib_get_train_position_intern: + // trackstate_segments_mutex, trackstate_trains_mutex, bidib_state_trains_rwlock >= read t_bidib_train_state_intern *train_state; t_bidib_train_position_query query; for (size_t i = 0; i < bidib_track_state.trains->len; i++) { @@ -687,8 +761,9 @@ void bidib_state_update_train_available(void) { } void bidib_state_reset(void) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); - + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For accessing bidib_track_state.points_board, .points_dcc, .signals_board, .signals_dcc + pthread_mutex_lock(&trackstate_accessories_mutex); t_bidib_board_accessory_state *board_accessory_state; for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { board_accessory_state = &g_array_index(bidib_track_state.points_board, @@ -727,7 +802,10 @@ void bidib_state_reset(void) { dcc_accessory_state->data.time_unit = BIDIB_TIMEUNIT_MILLISECONDS; dcc_accessory_state->data.switch_time = 0x00; } + pthread_mutex_unlock(&trackstate_accessories_mutex); + // For accessing bidib_track_state.peripherals + pthread_mutex_lock(&trackstate_peripherals_mutex); t_bidib_peripheral_state *peripheral_state; for (size_t i = 0; i < bidib_track_state.peripherals->len; i++) { peripheral_state = &g_array_index(bidib_track_state.peripherals, @@ -737,7 +815,10 @@ void bidib_state_reset(void) { peripheral_state->data.time_unit = BIDIB_TIMEUNIT_MILLISECONDS; peripheral_state->data.wait = 0x00; } + pthread_mutex_unlock(&trackstate_peripherals_mutex); + // For accessing bidib_track_state.segments + pthread_mutex_lock(&trackstate_segments_mutex); t_bidib_segment_state_intern *segment_state; for (size_t i = 0; i < bidib_track_state.segments->len; i++) { segment_state = &g_array_index(bidib_track_state.segments, @@ -754,7 +835,10 @@ void bidib_state_reset(void) { segment_state->dcc_addresses->len); } } + pthread_mutex_unlock(&trackstate_segments_mutex); + // For accessing bidib_track_state.reversers + pthread_mutex_lock(&trackstate_reversers_mutex); t_bidib_reverser_state *reverser_state; for (size_t i = 0; i < bidib_track_state.reversers->len; i++) { reverser_state = &g_array_index(bidib_track_state.reversers, @@ -762,7 +846,10 @@ void bidib_state_reset(void) { reverser_state->data.state_id = NULL; reverser_state->data.state_value = BIDIB_REV_EXEC_STATE_UNKNOWN; } + pthread_mutex_unlock(&trackstate_reversers_mutex); + // For accessing bidib_track_state.trains + pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state; for (size_t i = 0; i < bidib_track_state.trains->len; i++) { train_state = &g_array_index(bidib_track_state.trains, @@ -782,7 +869,10 @@ void bidib_state_reset(void) { train_state->decoder_state.container2_storage_known = false; train_state->decoder_state.container3_storage_known = false; } + pthread_mutex_unlock(&trackstate_trains_mutex); + // For accessing bidib_track_state.boosters + pthread_mutex_lock(&trackstate_boosters_mutex); t_bidib_booster_state *booster_state; for (size_t i = 0; i < bidib_track_state.boosters->len; i++) { booster_state = &g_array_index(bidib_track_state.boosters, @@ -794,14 +884,18 @@ void bidib_state_reset(void) { booster_state->data.voltage_known = false; booster_state->data.temp_known = false; } + pthread_mutex_unlock(&trackstate_boosters_mutex); + // For accessing bidib_track_state.track_outputs + pthread_mutex_lock(&trackstate_track_outputs_mutex); t_bidib_track_output_state *track_output_state; for (size_t i = 0; i < bidib_track_state.track_outputs->len; i++) { track_output_state = &g_array_index(bidib_track_state.track_outputs, t_bidib_track_output_state, i); track_output_state->cs_state = BIDIB_CS_OFF; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_track_outputs_mutex); } void bidib_state_reset_train_params(void) { diff --git a/src/state/bidib_state_free.c b/src/state/bidib_state_free.c index 9e4197d..4b2a6f3 100644 --- a/src/state/bidib_state_free.c +++ b/src/state/bidib_state_free.c @@ -248,9 +248,10 @@ void bidib_state_free_single_train(t_bidib_train train) { } } +///TODO: Add locks/mutexes even though not strictly necessary/pretty defensive. void bidib_state_free(void) { + if (!bidib_running) { - if (bidib_initial_values.points != NULL) { for (size_t i = 0; i < bidib_initial_values.points->len; i++) { bidib_state_free_single_initial_value( diff --git a/src/state/bidib_state_getter.c b/src/state/bidib_state_getter.c index 2add444..bd94644 100644 --- a/src/state/bidib_state_getter.c +++ b/src/state/bidib_state_getter.c @@ -321,6 +321,7 @@ t_bidib_segment_state_intern bidib_state_get_segment_state( t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( t_bidib_node_address node_address, uint8_t number) { + // For bidib_state_get_board_ref_by_nodeaddr pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref_by_nodeaddr(node_address); if (board != NULL) { @@ -328,8 +329,9 @@ t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( const t_bidib_segment_mapping mapping_i = g_array_index(board->segments, t_bidib_segment_mapping, i); if (mapping_i.addr == number) { + t_bidib_segment_state_intern *ret = bidib_state_get_segment_state_ref(mapping_i.id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - return bidib_state_get_segment_state_ref(mapping_i.id->str); + return ret; } } } @@ -338,11 +340,14 @@ t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( } t_bidib_reverser_state *bidib_state_get_reverser_state_ref(const char *reverser) { + if (reverser == NULL) { + return NULL; + } t_bidib_reverser_state *reverser_state_i; for (size_t i = 0; i < bidib_track_state.reversers->len; i++) { reverser_state_i = &g_array_index(bidib_track_state.reversers, t_bidib_reverser_state, i); - if (!strcmp(reverser_state_i->id, reverser)) { + if (strcmp(reverser_state_i->id, reverser) == 0) { return reverser_state_i; } } @@ -447,7 +452,7 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( t_bidib_node_address node_address) { t_bidib_booster_state *booster_state = NULL; pthread_rwlock_rdlock(&bidib_state_boards_rwlock); - t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); + const t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); if (sender != NULL) { booster_state = bidib_state_get_booster_state_ref(sender->id->str); } @@ -459,7 +464,7 @@ t_bidib_track_output_state *bidib_state_get_track_output_state_ref_by_nodeaddr( t_bidib_node_address node_address) { t_bidib_track_output_state *track_output_state = NULL; pthread_rwlock_rdlock(&bidib_state_boards_rwlock); - t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); + const t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); if (sender != NULL) { track_output_state = bidib_state_get_track_output_state_ref(sender->id->str); } diff --git a/src/state/bidib_state_getter_intern.h b/src/state/bidib_state_getter_intern.h index 0b70d4d..2f08134 100644 --- a/src/state/bidib_state_getter_intern.h +++ b/src/state/bidib_state_getter_intern.h @@ -55,7 +55,8 @@ t_bidib_board *bidib_state_get_board_ref_by_uniqueid(t_bidib_unique_id_mod uniqu /** * Returns the reference to the booster state with the given id. - * Must only be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_boosters_mutex acquired. + * Old: Must only be called with bidib_state_track_rwlock >=read acquired. * * @param booster the id of the booster. * @return NULL if not found, otherwise the reference to the booster state. @@ -64,7 +65,8 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref(const char *booster); /** * Returns the reference to the track output state with the given id. - * Must only be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_track_outputs_mutex acquired. + * Old: Must only be called with bidib_state_track_rwlock >=read acquired. * * @param track_output the id of the track output state. * @return NULL if not found, otherwise the reference to the track output state. @@ -97,7 +99,8 @@ t_bidib_board_accessory_mapping *bidib_state_get_board_accessory_mapping_ref_by_ /** * Returns the reference to the board accessory state with the given id. - * Must only be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_accessories_mutex acquired. + * Old: Must only be called with bidib_state_track_rwlock >=read acquired. * * @param accessory the id of the board accessory state. * @param point whether the accessory is a point or a signal. @@ -108,7 +111,8 @@ t_bidib_board_accessory_state *bidib_state_get_board_accessory_state_ref(const c /** * Returns the reference to the dcc accessory mapping with the given id. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with trackstate_accessories_mutex acquired. + * Old: Must only be called with bidib_state_boards_rwlock >=read acquired. * * @param accessory the id of the dcc accessory. * @param point whether the accessory is a point or a signal. @@ -119,7 +123,7 @@ t_bidib_dcc_accessory_mapping *bidib_state_get_dcc_accessory_mapping_ref( /** * Returns the reference to the dcc accessory mapping with the given dcc address. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >=read acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -132,7 +136,8 @@ t_bidib_dcc_accessory_mapping *bidib_state_get_dcc_accessory_mapping_ref_by_dcca /** * Returns the reference to the dcc accessory state with the given id. - * Must only be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_accessories_mutex acquired. + * Old: Must only be called with bidib_state_track_rwlock >=read acquired. * * @param accessory the id of the dcc accessory state. * @param point whether the accessory is a point or a signal. @@ -163,7 +168,8 @@ t_bidib_peripheral_mapping *bidib_state_get_peripheral_mapping_ref_by_port( /** * Returns the reference to the peripheral state with the given id. - * Must only be called with the bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_peripherals_mutex acquired. + * Old: Must only be called with the bidib_state_track_rwlock >=read acquired. * * @param peripheral the id of the peripheral. * @return NULL if not found, otherwise the reference to the peripheral state. @@ -172,7 +178,8 @@ t_bidib_peripheral_state *bidib_state_get_peripheral_state_ref(const char *perip /** * Returns the reference to the segment state with the given id. - * Must only be called with the bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_segments_mutex acquired. + * Old: Must only be called with the bidib_state_track_rwlock >=read acquired. * * @param segment the id of the segment. * @return NULL if not found, otherwise the reference to the segment state. @@ -180,17 +187,21 @@ t_bidib_peripheral_state *bidib_state_get_peripheral_state_ref(const char *perip t_bidib_segment_state_intern *bidib_state_get_segment_state_ref(const char *segment); /** - * Returns the occupancy state of a section. + * Returns a deep copy of the segment state * - * @param segment the id of the segment. - * @return the occupancy state. Must be freed by the caller. + * @param segment the segment state + * @return the segment state. Must be freed by the caller. */ t_bidib_segment_state_intern bidib_state_get_segment_state( const t_bidib_segment_state_intern *const segment); /** * Returns the reference to the segment state with the given id. - * Must only be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_segments_mutex acquired. + * Note: uses bidib_state_boards_rwlock internally, so shall not be called + * with bidib_state_boards_rwlock already acquired. + * + * Old: Must only be called with bidib_state_track_rwlock >=read acquired. * * @param node_address the node address of the board. * @param number the number on the board. @@ -201,7 +212,8 @@ t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( /** * Returns the reference to the reverser state with the given id. - * Must only be called with the bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_reversers_mutex acquired. + * Old: Must only be called with the bidib_state_track_rwlock >=read acquired. * * @param reverser the id of the reverser. * @return NULL if not found, otherwise the reference to the reverser state. @@ -248,7 +260,10 @@ t_bidib_train *bidib_state_get_train_ref(const char *train); /** * Returns the reference to the train state with the given dcc address. - * Must only be called with bidib_state_trains_rwlock >=read acquired + * Shall only be called with bidib_state_trains_rwlock >=read acquired, + * and with trackstate_trains_mutex acquired. + * + * Old: Must only be called with bidib_state_trains_rwlock >=read acquired * and bidib_state_track_rwlock >=read acquired. * * @param dcc_address the dcc address of the train. @@ -259,7 +274,7 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref_by_dccaddr( /** * Returns the reference to the train peripheral state with the given bit. - * Must only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_state_trains_rwlock >=read acquired. * * @param train_state the train state. * @param bit the bit of the peripheral. @@ -270,7 +285,9 @@ t_bidib_train_peripheral_state *bidib_state_get_train_peripheral_state_by_bit( /** * Returns the reference to the train state with the given id. - * Must be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_trains_mutex acquired. + * + * Old: Must be called with bidib_state_track_rwlock >=read acquired. * * @param train the id of the train state. * @return NULL if not found, otherwise the reference to the train state. @@ -279,7 +296,10 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref(const char *train); /** * Returns the reference to the booster state with the given node address. - * Must be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_boosters_mutex acquired. + * Note: uses bidib_state_boards_rwlock internally. + * + * Old: Must be called with bidib_state_track_rwlock >=read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the booster state. @@ -289,7 +309,10 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( /** * Returns the reference to the track output state with the given node address. - * Must be called with bidib_state_track_rwlock >=read acquired. + * Shall only be called with trackstate_track_outputs_mutex acquired. + * Note: uses bidib_state_boards_rwlock internally. + * + * Old: Must be called with bidib_state_track_rwlock >=read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the track output state. diff --git a/src/state/bidib_state_intern.h b/src/state/bidib_state_intern.h index 8ad0020..3e08141 100644 --- a/src/state/bidib_state_intern.h +++ b/src/state/bidib_state_intern.h @@ -37,16 +37,16 @@ typedef struct { - GArray *points_board; - GArray *points_dcc; - GArray *signals_board; - GArray *signals_dcc; - GArray *peripherals; - GArray *segments; - GArray *reversers; - GArray *trains; - GArray *boosters; - GArray *track_outputs; + GArray *points_board; // guarded by trackstate_accessories_mutex + GArray *points_dcc; // guarded by trackstate_accessories_mutex + GArray *signals_board; // guarded by trackstate_accessories_mutex + GArray *signals_dcc; // guarded by trackstate_accessories_mutex + GArray *peripherals; // guarded by trackstate_peripherals_mutex + GArray *segments; // guarded by trackstate_segments_mutex + GArray *reversers; // guarded by trackstate_reversers_mutex + GArray *trains; // guarded by trackstate_trains_mutex + GArray *boosters; // guarded by trackstate_boosters_mutex + GArray *track_outputs; // guarded by trackstate_track_outputs_mutex } t_bidib_track_state_intern; typedef struct { @@ -168,9 +168,18 @@ typedef struct { } t_bidib_state_initial_values; extern pthread_rwlock_t bidib_state_trains_rwlock; -extern pthread_rwlock_t bidib_state_track_rwlock; +//extern pthread_rwlock_t bidib_state_track_rwlock; extern pthread_rwlock_t bidib_state_boards_rwlock; +extern pthread_mutex_t trackstate_accessories_mutex; +extern pthread_mutex_t trackstate_peripherals_mutex; +extern pthread_mutex_t trackstate_segments_mutex; +extern pthread_mutex_t trackstate_reversers_mutex; +extern pthread_mutex_t trackstate_trains_mutex; +extern pthread_mutex_t trackstate_boosters_mutex; +extern pthread_mutex_t trackstate_track_outputs_mutex; + + extern t_bidib_state_initial_values bidib_initial_values; extern t_bidib_track_state_intern bidib_track_state; extern GArray *bidib_boards; @@ -407,7 +416,8 @@ void bidib_state_free_single_segment_state_intern(t_bidib_segment_state_intern s /** * Checks whether a dcc address is already used by a train, point or signal. - * Must only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_state_trains_rwlock >=read acquired. + * Note: uses bidib_state_boards_rwlock internally. * * @param dcc_address the dcc address which should be checked. * @return true if the dcc address is already in use, otherwise false. @@ -459,7 +469,10 @@ void bidib_state_add_initial_train_value(t_bidib_state_train_initial_value value /** * Updates the available state for all trains. - * Must only be called with bidib_state_trains_rwlock >=read acquired, + * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * and with trackstate_segments_mutex and trackstate_trains_mutex acquired. + * + * Old: Must only be called with bidib_state_trains_rwlock >=read acquired, * and bidib_state_track_rwlock write acquired. */ void bidib_state_update_train_available(void); diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 415e93b..2eb7afb 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -38,7 +38,10 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, const uint8_t *const value_list, unsigned int action_id) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_reverser_state_ref + pthread_mutex_lock(&trackstate_reversers_mutex); + // For bidib_state_get_reverser_mapping_ref_by_cv pthread_rwlock_rdlock(&bidib_state_boards_rwlock); uint8_t name_len = value_list[0]; @@ -52,6 +55,11 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, if (mapping != NULL) { t_bidib_reverser_state *reverser_state = bidib_state_get_reverser_state_ref(mapping->id->str); + ///NOTE: This is a shallow copy/not a strdup. + ///TODO: Change to deep copy, as otherwise the lock/mutex protection is not accurate + // anymore: mapping is a part of the boards, whilst the reverser state is part of + // the trackstate. + // Will have to adjust all other positions where this is assigned/reset. reverser_state->data.state_id = mapping->id->str; switch (value[0]) { case '0': @@ -80,11 +88,15 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, free(value); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); } void bidib_state_boost_state(t_bidib_node_address node_address, uint8_t power_state) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_booster_state_ref_by_nodeaddr + pthread_mutex_lock(&trackstate_boosters_mutex); + t_bidib_booster_state *booster_state = bidib_state_get_booster_state_ref_by_nodeaddr(node_address); if (booster_state != NULL) { @@ -96,13 +108,17 @@ void bidib_state_boost_state(t_bidib_node_address node_address, uint8_t power_st "No booster configured with node address 0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_boosters_mutex); } void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t number, uint8_t aspect, uint8_t total, uint8_t execution, uint8_t wait, unsigned int action_id) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_board_accessory_state_ref + pthread_mutex_lock(&trackstate_accessories_mutex); + // For bidib_state_get_board_accessory_mapping_ref_by_number pthread_rwlock_rdlock(&bidib_state_boards_rwlock); bool point; const t_bidib_board_accessory_mapping *const accessory_mapping = @@ -157,7 +173,8 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb number, node_address.top, node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); } void bidib_state_node_new(t_bidib_node_address node_address, uint8_t local_addr, @@ -228,7 +245,10 @@ void bidib_state_node_lost(t_bidib_unique_id_mod unique_id) { void bidib_state_cs_state(t_bidib_node_address node_address, uint8_t state, unsigned int action_id) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_track_output_state_ref_by_nodeaddr + pthread_mutex_lock(&trackstate_track_outputs_mutex); + t_bidib_track_output_state *track_output_state = bidib_state_get_track_output_state_ref_by_nodeaddr(node_address); if (track_output_state != NULL) { @@ -242,12 +262,18 @@ void bidib_state_cs_state(t_bidib_node_address node_address, uint8_t state, "No track output configured for node address 0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_track_outputs_mutex); } void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, unsigned int action_id) { + // For bidib_state_get_train_state_ref_by_dccaddr and bidib_state_dcc_addr_in_use pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref_by_dccaddr + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref_by_dccaddr(dcc_address); if (train_state != NULL) { @@ -263,7 +289,8 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, unsi dcc_address.addrh, dcc_address.addrl); } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } @@ -283,7 +310,10 @@ void bidib_state_cs_accessory_ack(t_bidib_node_address node_address, } void bidib_state_cs_drive(t_bidib_cs_drive_mod params) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref_by_dccaddr + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref_by_dccaddr(params.dcc_address); t_bidib_train_peripheral_state *peripheral_state; @@ -366,7 +396,8 @@ void bidib_state_cs_drive(t_bidib_cs_drive_mod params) { params.dcc_address.addrh, params.dcc_address.addrl); } } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); } void bidib_state_cs_accessory_manual(t_bidib_node_address node_address, @@ -429,8 +460,14 @@ void bidib_state_cs_accessory(t_bidib_node_address node_address, void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_port port, uint8_t portstat, unsigned int action_id) { t_bidib_peripheral_state *peripheral_state; - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + // For bidib_state_get_peripheral_state_ref + pthread_mutex_lock(&trackstate_peripherals_mutex); + // For bidib_state_get_peripheral_mapping_ref_by_port pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + const t_bidib_peripheral_mapping *const peripheral_mapping = bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); if (peripheral_mapping != NULL && @@ -465,14 +502,21 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_peripherals_mutex); } void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_port port, uint8_t time) { t_bidib_peripheral_state *peripheral_state; - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + // For bidib_state_get_peripheral_state_ref + pthread_mutex_lock(&trackstate_peripherals_mutex); + // For bidib_state_get_peripheral_mapping_ref_by_port pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + const t_bidib_peripheral_mapping *const peripheral_mapping = bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); if (peripheral_mapping != NULL && @@ -491,9 +535,19 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_peripherals_mutex); } +/** + * Logging utility for if a known or unknown train enters/exits a segment. + * Shall only be called with bidib_state_trains_rwlock >=read acquired, + * and with trackstate_trains_mutex acquired. + * + * @param detected if the train was detected (=entered, true) or left (=exited, false) a segment + * @param dcc_address the dcc address of the train + * @param segment_state the segment state, used only to log the ID/name of the segment + */ void bidib_state_log_train_detect(bool detected, const t_bidib_dcc_address *const dcc_address, const t_bidib_segment_state_intern *const segment_state) { const t_bidib_train_state_intern *const train_state = @@ -526,8 +580,15 @@ void bidib_state_log_train_detect(bool detected, const t_bidib_dcc_address *cons } void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool occ) { + // For bidib_state_log_train_detect and bidib_state_update_train_available pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + pthread_mutex_lock(&trackstate_segments_mutex); + // For bidib_state_log_train_detect and bidib_state_update_train_available + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_segment_state_intern *segment_state = bidib_state_get_segment_state_ref_by_nodeaddr(node_address, number); if (segment_state != NULL) { @@ -549,15 +610,23 @@ void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool "0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); + pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, uint8_t size, const uint8_t *const data) { t_bidib_segment_state_intern *segment_state; + // For bidib_state_log_train_detect and bidib_state_update_train_available pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + pthread_mutex_lock(&trackstate_segments_mutex); + // For bidib_state_log_train_detect and bidib_state_update_train_available + pthread_mutex_lock(&trackstate_trains_mutex); for (size_t i = 0; i < size; i++) { if (number + i < 255) { segment_state = bidib_state_get_segment_state_ref_by_nodeaddr( @@ -586,14 +655,20 @@ void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, } } bidib_state_update_train_available(); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); + pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_void, uint8_t freeze, uint8_t nosignal, unsigned int action_id) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_segment_state_ref + pthread_mutex_lock(&trackstate_segments_mutex); + // For bidib_state_get_board_ref_by_nodeaddr pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + const t_bidib_board *const board = bidib_state_get_board_ref_by_nodeaddr(node_address); if (board != NULL) { t_bidib_segment_state_intern *segment_state; @@ -633,9 +708,19 @@ void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_v node_address.top, node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); } +/** + * Check for new and lost dcc addresses in segment state and log accordingly. + * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * and with trackstate_trains_mutex acquired. + * + * @param segment_state_intern_query the segment for which to log address changes, state with old addrs. + * @param address_count number of addresses in addresses array + * @param addresses current/new addresses for the segment + */ void bidib_state_bm_address_log_changes( const t_bidib_segment_state_intern *const segment_state_intern_query, uint8_t address_count, const uint8_t *const addresses) { @@ -696,12 +781,20 @@ void bidib_state_bm_address_log_changes( void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, uint8_t address_count, const uint8_t *const addresses) { + // For bidib_state_update_train_available and bidib_state_bm_address_log_changes pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + pthread_mutex_lock(&trackstate_segments_mutex); + // For bidib_state_update_train_available and bidib_state_bm_address_log_changes + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_segment_state_intern *segment_state = bidib_state_get_segment_state_ref_by_nodeaddr(node_address, number); if (segment_state != NULL) { - // make a copy of the current decoder addresses for logging purposes + // make a copy of the current decoder addresses, + // bidib_state_bm_address_log_changes uses this to detect and log the address changes t_bidib_segment_state_intern segment_state_intern_query = bidib_state_get_segment_state(segment_state); if (segment_state->dcc_addresses->len > 0) { @@ -732,13 +825,17 @@ void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, "0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); + pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } void bidib_state_bm_current(t_bidib_node_address node_address, uint8_t number, uint8_t current) { - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_segment_state_ref_by_nodeaddr + pthread_mutex_lock(&trackstate_segments_mutex); t_bidib_segment_state_intern *segment_state = bidib_state_get_segment_state_ref_by_nodeaddr(node_address, number); if (segment_state != NULL) { @@ -774,20 +871,24 @@ void bidib_state_bm_current(t_bidib_node_address node_address, uint8_t number, } else { segment_state->power_consumption.known = false; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); } else { - pthread_rwlock_unlock(&bidib_state_track_rwlock); syslog_libbidib(LOG_ERR, "No segment with number 0x%02x configured for node address " "0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_segments_mutex); } -void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, - uint8_t speedh) { +void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, uint8_t speedh) { + // For bidib_state_get_train_state_ref_by_dccaddr pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref_by_dccaddr + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref_by_dccaddr(dcc_address); if (train_state != NULL) { @@ -797,14 +898,20 @@ void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, "No train configured for dcc address 0x%02x 0x%02x", dcc_address.addrl, dcc_address.addrh); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, uint8_t value, unsigned int action_id) { + // For bidib_state_get_train_state_ref_by_dccaddr pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref_by_dccaddr + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref_by_dccaddr(dcc_address); if (train_state != NULL) { @@ -853,23 +960,16 @@ void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, "No train configured for dcc address 0x%02x 0x%02x", dcc_address.addrl, dcc_address.addrh); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t length, const uint8_t *const diag_list, unsigned int action_id) { - struct timespec start; - clock_gettime(CLOCK_MONOTONIC, &start); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); - struct timespec end; - clock_gettime(CLOCK_MONOTONIC, &end); - - uint64_t mut_acq_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - if (mut_acq_us > 100000 /*0.1s*/) { - syslog_libbidib(LOG_WARNING, "bidib_state_boost_diagnostic: took %lld us to acquire track lock", mut_acq_us); - } - + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_booster_state_ref_by_nodeaddr + pthread_mutex_lock(&trackstate_boosters_mutex); t_bidib_booster_state *booster_state = bidib_state_get_booster_state_ref_by_nodeaddr(node_address); if (booster_state != NULL) { @@ -942,5 +1042,6 @@ void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t len "0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_boosters_mutex); } diff --git a/src/state/bidib_state_setter_intern.h b/src/state/bidib_state_setter_intern.h index 15e85c2..782a4ff 100644 --- a/src/state/bidib_state_setter_intern.h +++ b/src/state/bidib_state_setter_intern.h @@ -107,7 +107,10 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, /** * Sets the ack info for an dcc accessory. - * Must be called with bidib_state_track_rwlock write lock acquired, + * Shall only be called with trackstate_accessories_mutex acquired, + * and bidib_state_boards_rwlock >= read lock acquired. + * + * Old: Must be called with bidib_state_track_rwlock write lock acquired, * and bidib_state_boards_rwlock read or write lock acquired. * * @param node_address the node address of the board. @@ -119,7 +122,8 @@ void bidib_state_cs_accessory_ack(t_bidib_node_address node_address, /** * Sets the reported info about a manual train drive operation. - * Must only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_state_trains_rwlock >=read acquired. + * Note: uses trackstate_trains_mutex locally. * * @param params the parameters for the drive command. */ @@ -127,7 +131,11 @@ void bidib_state_cs_drive(t_bidib_cs_drive_mod params); /** * Sets the reported info about manual dcc accessory operation. - * Must only be called with bidib_state_track_rwlock write acquired. + * Shall only be called with trackstate_accessories_mutex acquired, + * and with bidib_state_boards_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock write acquired, + * and with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -138,7 +146,10 @@ void bidib_state_cs_accessory_manual(t_bidib_node_address node_address, /** * Sets the new state for a dcc accessory. - * Must only be called with bidib_state_track_rwlock write acquired, + * Shall only be called with trackstate_accessories_mutex acquired, + * and with bidib_state_boards_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock write acquired, * and with bidib_state_boards_rwlock >=read acquired. * * @param node_address the node address of the board. @@ -170,8 +181,8 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p /** * Sets the occupancy state of a segment. - * Must be called with none of trains/track/board - * rwlocks acquired. + * Shall be called with none of trains/board rwlocks and/or trackstate mutexes acquired. + * * * @param node_address the node address of the board. * @param number the number of the segment. diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index f4fb476..024a0b3 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -375,12 +375,15 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, message, action_id); dcc_address.addrl = message[data_index]; dcc_address.addrh = message[data_index + 1]; - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // Both for bidib_state_cs_accessory_ack + pthread_mutex_lock(&trackstate_accessories_mutex); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); bidib_state_cs_accessory_ack(node_address, dcc_address, message[data_index + 2]); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); free(message); break; case MSG_CS_DRIVE_MANUAL: @@ -408,12 +411,14 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, message, action_id); dcc_address.addrl = message[data_index]; dcc_address.addrh = message[data_index + 1]; - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // Both for bidib_state_cs_accessory_manual + pthread_mutex_lock(&trackstate_accessories_mutex); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); - bidib_state_cs_accessory_manual(node_address, dcc_address, - message[data_index + 2]); + bidib_state_cs_accessory_manual(node_address, dcc_address, message[data_index + 2]); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_accessories_mutex); free(message); break; case MSG_LC_STAT: diff --git a/test/unit/bidib_highlevel_message_tests.c b/test/unit/bidib_highlevel_message_tests.c index 2b24fd2..8f7fd3e 100644 --- a/test/unit/bidib_highlevel_message_tests.c +++ b/test/unit/bidib_highlevel_message_tests.c @@ -94,12 +94,15 @@ static void set_all_boards_and_trains_connected(void) { } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref("train1"); if (train_state != NULL) { train_state->on_track = true; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); } static void set_board_point_is_sent_correctly(void **state __attribute__((unused))) { diff --git a/test/unit/bidib_parallel_tests.c b/test/unit/bidib_parallel_tests.c index 5bc670e..4eabc08 100644 --- a/test/unit/bidib_parallel_tests.c +++ b/test/unit/bidib_parallel_tests.c @@ -76,7 +76,11 @@ static void set_all_boards_and_trains_connected(void) { } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_wrlock(&bidib_state_track_rwlock); + + //pthread_rwlock_wrlock(&bidib_state_track_rwlock); + // For bidib_state_get_train_state_ref + pthread_mutex_lock(&trackstate_trains_mutex); + t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref("train1"); if (train_state != NULL) { train_state->on_track = true; @@ -85,7 +89,8 @@ static void set_all_boards_and_trains_connected(void) { if (train_state != NULL) { train_state->on_track = true; } - pthread_rwlock_unlock(&bidib_state_track_rwlock); + //pthread_rwlock_unlock(&bidib_state_track_rwlock); + pthread_mutex_unlock(&trackstate_trains_mutex); } static void set_board_point(const char *point, const char *aspect) { From 6cf84d9bfb32a13d4996720df130943c7a41b956 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Thu, 28 Nov 2024 17:17:48 +0100 Subject: [PATCH 21/51] check other locks, documentation, naming --- src/highlevel/bidib_highlevel_admin.c | 4 ++ src/highlevel/bidib_highlevel_getter.c | 14 ++++ src/highlevel/bidib_highlevel_setter.c | 15 +++-- src/lowlevel/bidib_lowlevel_intern.h | 8 +-- src/state/bidib_state.c | 3 + src/state/bidib_state_free.c | 3 +- src/state/bidib_state_getter.c | 2 + src/state/bidib_state_getter_intern.h | 66 ++++++++++--------- src/state/bidib_state_intern.h | 1 + src/state/bidib_state_setter.c | 2 + src/state/bidib_state_setter_intern.h | 8 +-- src/transmission/bidib_transmission_receive.c | 6 +- src/transmission/bidib_transmission_send.c | 6 +- 13 files changed, 87 insertions(+), 51 deletions(-) diff --git a/src/highlevel/bidib_highlevel_admin.c b/src/highlevel/bidib_highlevel_admin.c index f6a60a9..c93fd3b 100644 --- a/src/highlevel/bidib_highlevel_admin.c +++ b/src/highlevel/bidib_highlevel_admin.c @@ -41,6 +41,7 @@ int bidib_ping(const char *board, uint8_t ping_byte) { syslog_libbidib(LOG_ERR, "Ping: parameters must not be NULL"); return 1; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { @@ -64,6 +65,7 @@ int bidib_identify(const char *board, uint8_t state) { syslog_libbidib(LOG_ERR, "Identify: parameters must not be NULL"); return 1; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { @@ -87,6 +89,7 @@ int bidib_get_protocol_version(const char *board) { syslog_libbidib(LOG_ERR, "Get protocol version: parameters must not be NULL"); return 1; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { @@ -110,6 +113,7 @@ int bidib_get_software_version(const char *board) { syslog_libbidib(LOG_ERR, "Get software version: parameters must not be NULL"); return 1; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { diff --git a/src/highlevel/bidib_highlevel_getter.c b/src/highlevel/bidib_highlevel_getter.c index d875c97..dfebb20 100644 --- a/src/highlevel/bidib_highlevel_getter.c +++ b/src/highlevel/bidib_highlevel_getter.c @@ -310,6 +310,7 @@ bool bidib_get_board_connected(const char *board) { return false; } bool res = false; + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const tmp = bidib_state_get_board_ref(board); if (tmp != NULL) { @@ -324,6 +325,7 @@ t_bidib_board_features_query bidib_get_board_features(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const tmp = bidib_state_get_board_ref(board); if (tmp != NULL && tmp->features->len != 0) { @@ -357,6 +359,7 @@ t_bidib_unique_id_query bidib_get_uniqueid(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && board_ref->unique_id.class_id != 0xFF) { @@ -370,6 +373,7 @@ t_bidib_unique_id_query bidib_get_uniqueid(const char *board) { t_bidib_unique_id_query bidib_get_uniqueid_by_nodeaddr(t_bidib_node_address node_address) { t_bidib_unique_id_query query; query.known = false; + // For bidib_state_get_board_ref_by_nodeaddr pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref_by_nodeaddr(node_address); if (board_ref != NULL && board_ref->connected) { @@ -386,6 +390,7 @@ t_bidib_node_address_query bidib_get_nodeaddr(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && board_ref->connected) { @@ -417,6 +422,7 @@ t_bidib_id_list_query bidib_get_board_points(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->points_board->len > 0 || @@ -452,6 +458,7 @@ t_bidib_id_list_query bidib_get_board_signals(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->signals_board->len > 0 || @@ -487,6 +494,7 @@ t_bidib_id_list_query bidib_get_board_peripherals(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->peripherals->len > 0)) { @@ -509,6 +517,7 @@ t_bidib_id_list_query bidib_get_board_segments(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->segments->len > 0)) { @@ -531,6 +540,7 @@ t_bidib_id_list_query bidib_get_board_reversers(const char *board) { if (board == NULL) { return query; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->reversers->len > 0)) { @@ -1175,6 +1185,7 @@ t_bidib_dcc_address_query bidib_get_train_dcc_addr(const char *train) { if (train == NULL) { return query; } + // For bidib_state_get_train_ref pthread_rwlock_rdlock(&bidib_state_trains_rwlock); const t_bidib_train *const tmp = bidib_state_get_train_ref(train); if (tmp != NULL) { @@ -1192,6 +1203,7 @@ t_bidib_id_list_query bidib_get_train_peripherals(const char *train) { if (train == NULL) { return query; } + // For bidib_state_get_train_ref pthread_rwlock_rdlock(&bidib_state_trains_rwlock); const t_bidib_train *const tmp = bidib_state_get_train_ref(train); if (tmp != NULL) { @@ -1401,6 +1413,7 @@ static t_bidib_id_list_query bidib_get_accessory_aspects(const char *accessory, if (accessory == NULL) { return query; } + // For bidib_state_get_board_accessory_mapping_ref, bidib_state_get_dcc_accessory_mapping_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board_accessory_mapping *const board_mapping = bidib_state_get_board_accessory_mapping_ref(accessory, point); @@ -1447,6 +1460,7 @@ t_bidib_id_list_query bidib_get_peripheral_aspects(const char *peripheral) { if (peripheral == NULL) { return query; } + // For bidib_state_get_peripheral_mapping_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_peripheral_mapping *const peripheral_mapping = bidib_state_get_peripheral_mapping_ref(peripheral); diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index e804319..1a1dac3 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -445,7 +445,6 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra t_bidib_node_address tmp_addr = board->node_addr; pthread_rwlock_unlock(&bidib_state_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); - bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); return 0; } @@ -453,6 +452,7 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra int bidib_set_train_speed(const char *train, int speed, const char *track_output) { int ret = 0; + // For bidib_set_train_speed_internal pthread_rwlock_wrlock(&bidib_state_trains_rwlock); ret = bidib_set_train_speed_internal(train, speed, track_output); pthread_rwlock_unlock(&bidib_state_trains_rwlock); @@ -468,6 +468,7 @@ int bidib_set_calibrated_train_speed(const char *train, int speed, const char *t syslog_libbidib(LOG_ERR, "Set calibrated train speed: speed must be in range -9...9"); return 1; } + // For bidib_state_get_train_ref and bidib_set_train_speed_internal pthread_rwlock_wrlock(&bidib_state_trains_rwlock); const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); if (tmp_train == NULL) { @@ -504,9 +505,12 @@ int bidib_emergency_stop_train(const char *train, const char *track_output) { syslog_libbidib(LOG_ERR, "Emergency stop train: parameters must not be NULL"); return 1; } + // For bidib_state_get_train_ref pthread_rwlock_wrlock(&bidib_state_trains_rwlock); - const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + + const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (tmp_train == NULL) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); @@ -564,9 +568,8 @@ int bidib_emergency_stop_train(const char *train, const char *track_output) { /** * Get the current bit(s) for the train peripherals. - * Shall only be called with trackstate_trains_mutex acquired; - * And if the passed "train" param is a part of bidib_trains, - * which is very likely, then bidib_state_trains_rwlock >= read has to be acquired too. + * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * and with trackstate_trains_mutex acquired. * * @param train * @param start @@ -713,6 +716,7 @@ int bidib_set_booster_power_state(const char *booster, bool on) { syslog_libbidib(LOG_ERR, "Set booster power state: parameters must not be NULL"); return 1; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref(booster); if (board == NULL || !board->connected) { @@ -752,6 +756,7 @@ int bidib_set_track_output_state(const char *track_output, t_bidib_cs_state stat syslog_libbidib(LOG_ERR, "Set track output state: parameters must not be NULL"); return 1; } + // For bidib_state_get_board_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (board == NULL || !board->connected) { diff --git a/src/lowlevel/bidib_lowlevel_intern.h b/src/lowlevel/bidib_lowlevel_intern.h index cf42816..b54818a 100644 --- a/src/lowlevel/bidib_lowlevel_intern.h +++ b/src/lowlevel/bidib_lowlevel_intern.h @@ -31,11 +31,9 @@ #define BIDIB_LOWLEVEL_INTERN_H +#include #include - -extern pthread_rwlock_t bidib_state_trains_rwlock; - /** * Used to avoid the usage of a recursive rwlock. * Must call with param `lock` false if bidib_state_trains_rwlock @@ -65,7 +63,7 @@ void bidib_send_cs_drive_intern(t_bidib_node_address node_address, * no reference. */ void bidib_send_cs_accessory_intern(t_bidib_node_address node_address, - t_bidib_cs_accessory_mod cs_accessory_params, - unsigned int action_id); + t_bidib_cs_accessory_mod cs_accessory_params, + unsigned int action_id); #endif diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 05dc6ec..69ee083 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -409,6 +409,7 @@ t_bidib_bm_confidence_level bidib_bm_confidence_to_level(t_bidib_segment_state_c bool bidib_state_add_board(t_bidib_board board) { bool error = false; + // For bidib_state_get_board_ref, bidib_state_get_board_ref_by_uniqueid, and accessing bidib_boards pthread_rwlock_wrlock(&bidib_state_boards_rwlock); if (bidib_state_get_board_ref(board.id->str) != NULL || bidib_state_get_board_ref_by_uniqueid(board.unique_id) != NULL) { @@ -906,6 +907,7 @@ void bidib_state_reset_train_params(void) { params.function2 = 0x00; params.function3 = 0x00; params.function4 = 0x00; + // For bidib_send_cs_drive_intern pthread_rwlock_wrlock(&bidib_state_trains_rwlock); for (size_t i = 0; i < bidib_trains->len; i++) { const t_bidib_train *const train_i = &g_array_index(bidib_trains, t_bidib_train, i); @@ -922,6 +924,7 @@ void bidib_state_reset_train_params(void) { params.dcc_format = 0x00; break; } + // For accessing bidib_boards pthread_rwlock_rdlock(&bidib_state_boards_rwlock); for (size_t j = 0; j < bidib_boards->len; j++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, j); diff --git a/src/state/bidib_state_free.c b/src/state/bidib_state_free.c index 4b2a6f3..aa18f7c 100644 --- a/src/state/bidib_state_free.c +++ b/src/state/bidib_state_free.c @@ -248,9 +248,8 @@ void bidib_state_free_single_train(t_bidib_train train) { } } -///TODO: Add locks/mutexes even though not strictly necessary/pretty defensive. + void bidib_state_free(void) { - if (!bidib_running) { if (bidib_initial_values.points != NULL) { for (size_t i = 0; i < bidib_initial_values.points->len; i++) { diff --git a/src/state/bidib_state_getter.c b/src/state/bidib_state_getter.c index bd94644..72a58ac 100644 --- a/src/state/bidib_state_getter.c +++ b/src/state/bidib_state_getter.c @@ -451,6 +451,7 @@ t_bidib_train_peripheral_state *bidib_state_get_train_peripheral_state_by_bit( t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( t_bidib_node_address node_address) { t_bidib_booster_state *booster_state = NULL; + // For bidib_state_get_board_ref_by_nodeaddr pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); if (sender != NULL) { @@ -463,6 +464,7 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( t_bidib_track_output_state *bidib_state_get_track_output_state_ref_by_nodeaddr( t_bidib_node_address node_address) { t_bidib_track_output_state *track_output_state = NULL; + // For bidib_state_get_board_ref_by_nodeaddr pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); if (sender != NULL) { diff --git a/src/state/bidib_state_getter_intern.h b/src/state/bidib_state_getter_intern.h index 2f08134..3fc7fd3 100644 --- a/src/state/bidib_state_getter_intern.h +++ b/src/state/bidib_state_getter_intern.h @@ -37,7 +37,7 @@ /** * Returns the reference to the board with the given id. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param board the id of the board. * @return NULL if not found, otherwise the reference to the board. @@ -46,7 +46,7 @@ t_bidib_board *bidib_state_get_board_ref(const char *board); /** * Returns the reference to the board with the given unique id. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param unique_id the unique id of the board. * @return NULL if not found, otherwise the reference to the board. @@ -56,7 +56,8 @@ t_bidib_board *bidib_state_get_board_ref_by_uniqueid(t_bidib_unique_id_mod uniqu /** * Returns the reference to the booster state with the given id. * Shall only be called with trackstate_boosters_mutex acquired. - * Old: Must only be called with bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param booster the id of the booster. * @return NULL if not found, otherwise the reference to the booster state. @@ -66,7 +67,8 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref(const char *booster); /** * Returns the reference to the track output state with the given id. * Shall only be called with trackstate_track_outputs_mutex acquired. - * Old: Must only be called with bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param track_output the id of the track output state. * @return NULL if not found, otherwise the reference to the track output state. @@ -75,7 +77,7 @@ t_bidib_track_output_state *bidib_state_get_track_output_state_ref(const char *t /** * Returns the reference to the board accessory mapping with the given id. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param accessory the id of the board accessory. * @param point whether the accessory is a point or a signal. @@ -86,7 +88,7 @@ t_bidib_board_accessory_mapping *bidib_state_get_board_accessory_mapping_ref( /** * Returns the reference to the board accessory mapping with the given number. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param number the number of the accessory. @@ -100,7 +102,8 @@ t_bidib_board_accessory_mapping *bidib_state_get_board_accessory_mapping_ref_by_ /** * Returns the reference to the board accessory state with the given id. * Shall only be called with trackstate_accessories_mutex acquired. - * Old: Must only be called with bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param accessory the id of the board accessory state. * @param point whether the accessory is a point or a signal. @@ -111,8 +114,7 @@ t_bidib_board_accessory_state *bidib_state_get_board_accessory_state_ref(const c /** * Returns the reference to the dcc accessory mapping with the given id. - * Shall only be called with trackstate_accessories_mutex acquired. - * Old: Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param accessory the id of the dcc accessory. * @param point whether the accessory is a point or a signal. @@ -123,7 +125,7 @@ t_bidib_dcc_accessory_mapping *bidib_state_get_dcc_accessory_mapping_ref( /** * Returns the reference to the dcc accessory mapping with the given dcc address. - * Shall only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -137,7 +139,8 @@ t_bidib_dcc_accessory_mapping *bidib_state_get_dcc_accessory_mapping_ref_by_dcca /** * Returns the reference to the dcc accessory state with the given id. * Shall only be called with trackstate_accessories_mutex acquired. - * Old: Must only be called with bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param accessory the id of the dcc accessory state. * @param point whether the accessory is a point or a signal. @@ -148,7 +151,7 @@ t_bidib_dcc_accessory_state *bidib_state_get_dcc_accessory_state_ref(const char /** * Returns the reference to the peripheral mapping with the given id. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param peripheral the id of the peripheral. * @return NULL if not found, otherwise the reference to the peripheral mapping. @@ -157,7 +160,7 @@ t_bidib_peripheral_mapping *bidib_state_get_peripheral_mapping_ref(const char *p /** * Returns the reference to the peripheral mapping with the given port. - * Must only be called with the bidib_state_boards_rwlock >=read acquired. + * Shall only be called with the bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param port the port of the peripheral. @@ -169,7 +172,8 @@ t_bidib_peripheral_mapping *bidib_state_get_peripheral_mapping_ref_by_port( /** * Returns the reference to the peripheral state with the given id. * Shall only be called with trackstate_peripherals_mutex acquired. - * Old: Must only be called with the bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with the bidib_state_track_rwlock >= read acquired. * * @param peripheral the id of the peripheral. * @return NULL if not found, otherwise the reference to the peripheral state. @@ -179,7 +183,8 @@ t_bidib_peripheral_state *bidib_state_get_peripheral_state_ref(const char *perip /** * Returns the reference to the segment state with the given id. * Shall only be called with trackstate_segments_mutex acquired. - * Old: Must only be called with the bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with the bidib_state_track_rwlock >= read acquired. * * @param segment the id of the segment. * @return NULL if not found, otherwise the reference to the segment state. @@ -187,10 +192,10 @@ t_bidib_peripheral_state *bidib_state_get_peripheral_state_ref(const char *perip t_bidib_segment_state_intern *bidib_state_get_segment_state_ref(const char *segment); /** - * Returns a deep copy of the segment state + * Returns a deep copy of the segment state. * * @param segment the segment state - * @return the segment state. Must be freed by the caller. + * @return the segment state. Pointer contents must be freed by the caller. */ t_bidib_segment_state_intern bidib_state_get_segment_state( const t_bidib_segment_state_intern *const segment); @@ -201,7 +206,7 @@ t_bidib_segment_state_intern bidib_state_get_segment_state( * Note: uses bidib_state_boards_rwlock internally, so shall not be called * with bidib_state_boards_rwlock already acquired. * - * Old: Must only be called with bidib_state_track_rwlock >=read acquired. + * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param node_address the node address of the board. * @param number the number on the board. @@ -213,7 +218,8 @@ t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( /** * Returns the reference to the reverser state with the given id. * Shall only be called with trackstate_reversers_mutex acquired. - * Old: Must only be called with the bidib_state_track_rwlock >=read acquired. + * + * Old: Must only be called with the bidib_state_track_rwlock >= read acquired. * * @param reverser the id of the reverser. * @return NULL if not found, otherwise the reference to the reverser state. @@ -222,7 +228,7 @@ t_bidib_reverser_state *bidib_state_get_reverser_state_ref(const char *reverser) /** * Returns the reference to the reverser mapping with the given CV. - * Must only be called with the bidib_state_boards_rwlock >=read acquired. + * Shall only be called with the bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param cv the CV of the reverser. @@ -233,7 +239,7 @@ t_bidib_reverser_mapping *bidib_state_get_reverser_mapping_ref_by_cv( /** * Returns the reference to the reverser mapping with the given id. - * Must only be called with the bidib_state_boards_rwlock >=read acquired. + * Shall only be called with the bidib_state_boards_rwlock >= read acquired. * * @param id the name of the reverser. * @return NULL if not found, otherwise the reference to the reverser mapping. @@ -242,7 +248,7 @@ t_bidib_reverser_mapping *bidib_state_get_reverser_mapping_ref(const char *rever /** * Returns the reference to the board with the given node address. - * Must only be called with bidib_state_boards_rwlock >=read acquired. + * Shall only be called with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the board. @@ -251,7 +257,7 @@ t_bidib_board *bidib_state_get_board_ref_by_nodeaddr(t_bidib_node_address node_a /** * Returns the reference to the train with the given id. - * Must only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_state_trains_rwlock >= read acquired. * * @param train the id of the train. * @return NULL if not found, otherwise the reference to the train. @@ -260,11 +266,11 @@ t_bidib_train *bidib_state_get_train_ref(const char *train); /** * Returns the reference to the train state with the given dcc address. - * Shall only be called with bidib_state_trains_rwlock >=read acquired, + * Shall only be called with bidib_state_trains_rwlock >= read acquired, * and with trackstate_trains_mutex acquired. * - * Old: Must only be called with bidib_state_trains_rwlock >=read acquired - * and bidib_state_track_rwlock >=read acquired. + * Old: Must only be called with bidib_state_trains_rwlock >= read acquired + * and bidib_state_track_rwlock >= read acquired. * * @param dcc_address the dcc address of the train. * @return NULL if not found, otherwise the reference to the train state. @@ -274,7 +280,7 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref_by_dccaddr( /** * Returns the reference to the train peripheral state with the given bit. - * Shall only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_state_trains_rwlock >= read acquired. * * @param train_state the train state. * @param bit the bit of the peripheral. @@ -287,7 +293,7 @@ t_bidib_train_peripheral_state *bidib_state_get_train_peripheral_state_by_bit( * Returns the reference to the train state with the given id. * Shall only be called with trackstate_trains_mutex acquired. * - * Old: Must be called with bidib_state_track_rwlock >=read acquired. + * Old: Must be called with bidib_state_track_rwlock >= read acquired. * * @param train the id of the train state. * @return NULL if not found, otherwise the reference to the train state. @@ -299,7 +305,7 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref(const char *train); * Shall only be called with trackstate_boosters_mutex acquired. * Note: uses bidib_state_boards_rwlock internally. * - * Old: Must be called with bidib_state_track_rwlock >=read acquired. + * Old: Must be called with bidib_state_track_rwlock >= read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the booster state. @@ -312,7 +318,7 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( * Shall only be called with trackstate_track_outputs_mutex acquired. * Note: uses bidib_state_boards_rwlock internally. * - * Old: Must be called with bidib_state_track_rwlock >=read acquired. + * Old: Must be called with bidib_state_track_rwlock >= read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the track output state. diff --git a/src/state/bidib_state_intern.h b/src/state/bidib_state_intern.h index 3e08141..39bff28 100644 --- a/src/state/bidib_state_intern.h +++ b/src/state/bidib_state_intern.h @@ -426,6 +426,7 @@ bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address); /** * Adds a train to the current state. + * Shall only be called with bidib_state_trains_rwlock >= read acquired. * * @param train the new train. * @return true if NULL or train already exists, otherwise false. diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 2eb7afb..e4bb356 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -179,6 +179,7 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb void bidib_state_node_new(t_bidib_node_address node_address, uint8_t local_addr, t_bidib_unique_id_mod unique_id) { + // For bidib_state_get_board_ref_by_uniqueid pthread_rwlock_wrlock(&bidib_state_boards_rwlock); t_bidib_board *board = bidib_state_get_board_ref_by_uniqueid(unique_id); if (board != NULL) { @@ -219,6 +220,7 @@ static bool bidib_state_is_subnode(t_bidib_node_address node_address, } void bidib_state_node_lost(t_bidib_unique_id_mod unique_id) { + // For bidib_state_get_board_ref_by_uniqueid pthread_rwlock_wrlock(&bidib_state_boards_rwlock); t_bidib_board *board = bidib_state_get_board_ref_by_uniqueid(unique_id); if (board != NULL) { diff --git a/src/state/bidib_state_setter_intern.h b/src/state/bidib_state_setter_intern.h index 782a4ff..e29d4b9 100644 --- a/src/state/bidib_state_setter_intern.h +++ b/src/state/bidib_state_setter_intern.h @@ -122,7 +122,7 @@ void bidib_state_cs_accessory_ack(t_bidib_node_address node_address, /** * Sets the reported info about a manual train drive operation. - * Shall only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_state_trains_rwlock >= read acquired. * Note: uses trackstate_trains_mutex locally. * * @param params the parameters for the drive command. @@ -132,7 +132,7 @@ void bidib_state_cs_drive(t_bidib_cs_drive_mod params); /** * Sets the reported info about manual dcc accessory operation. * Shall only be called with trackstate_accessories_mutex acquired, - * and with bidib_state_boards_rwlock >=read acquired. + * and with bidib_state_boards_rwlock >= read acquired. * * Old: Must only be called with bidib_state_track_rwlock write acquired, * and with bidib_state_boards_rwlock >= read acquired. @@ -147,10 +147,10 @@ void bidib_state_cs_accessory_manual(t_bidib_node_address node_address, /** * Sets the new state for a dcc accessory. * Shall only be called with trackstate_accessories_mutex acquired, - * and with bidib_state_boards_rwlock >=read acquired. + * and with bidib_state_boards_rwlock >= read acquired. * * Old: Must only be called with bidib_state_track_rwlock write acquired, - * and with bidib_state_boards_rwlock >=read acquired. + * and with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param params the parameters for the dcc accessory. diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 024a0b3..001f641 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -215,7 +215,7 @@ static void bidib_log_received_message(const uint8_t *const addr_stack, uint8_t syslog_libbidib(LOG_DEBUG, "Message bytes: %s", hex_string); } -// Must be called with bidib_state_boards_rwlock read lock acquired. +// Shall only be called with bidib_state_boards_rwlock >= read acquired. static void bidib_log_sys_error(const uint8_t *const message, t_bidib_node_address node_address, unsigned int action_id) { @@ -251,6 +251,7 @@ static void bidib_log_sys_error(const uint8_t *const message, g_string_free(fault_name, TRUE); } +// Shall only be called with bidib_state_boards_rwlock >= read acquired. static void bidib_log_boost_stat_error(const uint8_t *const message, t_bidib_node_address node_address, unsigned int action_id) { @@ -271,6 +272,7 @@ static void bidib_log_boost_stat_error(const uint8_t *const message, g_string_free(fault_name, TRUE); } +// Shall only be called with bidib_state_boards_rwlock >= read acquired. static void bidib_log_boost_stat_okay(const uint8_t *const message, t_bidib_node_address node_address, unsigned int action_id) { @@ -446,7 +448,7 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, bidib_state_bm_occ(node_address, message[data_index], true); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); board = bidib_state_get_board_ref_by_nodeaddr(node_address); - secack_on = (board != NULL && board->secack_on); + secack_on = board != NULL && board->secack_on; pthread_rwlock_unlock(&bidib_state_boards_rwlock); if (secack_on) { bidib_send_bm_mirror_occ(node_address, message[data_index], 0); diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 2e76481..eb86430 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -87,7 +87,7 @@ static void bidib_send_delimiter(void) { write_byte(BIDIB_PKT_MAGIC); } -// Must be called with bidib_send_buffer_mutex locked. +// Shall only be called with bidib_send_buffer_mutex locked. static void bidib_flush_impl_old(void) { if (buffer_index > 0) { uint8_t crc = 0; @@ -106,9 +106,9 @@ static void bidib_flush_impl_old(void) { } /** - * @brief Will flush the send cache, if possible in once go (as one batch); + * Will flush the send cache, if possible in once go (as one batch); * if batching not possible, then send byte-per-byte. - * Must be called with bidib_send_buffer_mutex locked. + * Shall only be called with bidib_send_buffer_mutex locked. * * How does it work? It copies the actual buffer (called `buffer`) * byte-per-byte to an auxiliary buffer (called `buffer_aux`), From 7d322b3d9b4aa70e09e5fb801dfc6be9f1457cae Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Thu, 28 Nov 2024 17:25:36 +0100 Subject: [PATCH 22/51] fix incorrect include --- src/lowlevel/bidib_lowlevel_intern.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lowlevel/bidib_lowlevel_intern.h b/src/lowlevel/bidib_lowlevel_intern.h index b54818a..587c9c7 100644 --- a/src/lowlevel/bidib_lowlevel_intern.h +++ b/src/lowlevel/bidib_lowlevel_intern.h @@ -31,7 +31,7 @@ #define BIDIB_LOWLEVEL_INTERN_H -#include +#include "../../include/definitions/bidib_definitions_custom.h" #include /** From bf2435417ebce64daf6d19fe3c963428757d63a2 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Thu, 28 Nov 2024 17:34:10 +0100 Subject: [PATCH 23/51] change heartbeat to be more visible for debugging. --- src/highlevel/bidib_highlevel_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 669f5af..05bce8f 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -271,7 +271,8 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { while (bidib_running) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - syslog_libbidib(LOG_DEBUG, "Heartbeat, time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); + ///TODO: Back to debug? + syslog_libbidib(LOG_WARNING, "Heartbeat, time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); sleep(2); } return NULL; From 19f0ec761878551dee17b0e7ef90b837b9e608ca Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 11:19:58 +0100 Subject: [PATCH 24/51] adjust heartbeat to report lock usage statistics --- src/highlevel/bidib_highlevel_util.c | 116 +++++++++++++++++++++++++-- test/physical/test_common.c | 8 +- 2 files changed, 115 insertions(+), 9 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 05bce8f..899d448 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -268,12 +268,118 @@ void syslog_libbidib(int priority, const char *format, ...) { } void *bidib_heartbeat_log(void *par __attribute__((unused))) { + uint32_t iters = 0; + uint32_t bidib_state_trains_rwlock_lockedcount = 0; + uint32_t trackstate_accessories_mutex_lockedcount = 0; + uint32_t trackstate_peripherals_mutex_lockedcount = 0; + uint32_t trackstate_segments_mutex_lockedcount = 0; + uint32_t trackstate_reversers_mutex_lockedcount = 0; + uint32_t trackstate_trains_mutex_lockedcount = 0; + uint32_t trackstate_boosters_mutex_lockedcount = 0; + uint32_t trackstate_track_outputs_mutex_lockedcount = 0; + uint32_t bidib_state_boards_rwlock_lockedcount = 0; + while (bidib_running) { - struct timespec tv; - clock_gettime(CLOCK_MONOTONIC, &tv); - ///TODO: Back to debug? - syslog_libbidib(LOG_WARNING, "Heartbeat, time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); - sleep(2); + //sleep(2); + //struct timespec tv; + //clock_gettime(CLOCK_MONOTONIC, &tv); + /////TODO: Back to debug? + //syslog_libbidib(LOG_WARNING, "Heartbeat, time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); + + // check the status of locked/unlocked mutexes. + iters++; + + if (pthread_rwlock_trywrlock(&bidib_state_trains_rwlock) == 0) { + pthread_rwlock_unlock(&bidib_state_trains_rwlock); + } else { + ++bidib_state_trains_rwlock_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_accessories_mutex) == 0) { + pthread_mutex_unlock(&trackstate_accessories_mutex); + } else { + ++trackstate_accessories_mutex_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_peripherals_mutex) == 0) { + pthread_mutex_unlock(&trackstate_peripherals_mutex); + } else { + ++trackstate_peripherals_mutex_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_segments_mutex) == 0) { + pthread_mutex_unlock(&trackstate_segments_mutex); + } else { + ++trackstate_segments_mutex_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_reversers_mutex) == 0) { + pthread_mutex_unlock(&trackstate_reversers_mutex); + } else { + ++trackstate_reversers_mutex_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_trains_mutex) == 0) { + pthread_mutex_unlock(&trackstate_trains_mutex); + } else { + ++trackstate_trains_mutex_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_boosters_mutex) == 0) { + pthread_mutex_unlock(&trackstate_boosters_mutex); + } else { + ++trackstate_boosters_mutex_lockedcount; + } + + if (pthread_mutex_trylock(&trackstate_track_outputs_mutex) == 0) { + pthread_mutex_unlock(&trackstate_track_outputs_mutex); + } else { + ++trackstate_track_outputs_mutex_lockedcount; + } + + if (pthread_rwlock_trywrlock(&bidib_state_boards_rwlock) == 0) { + pthread_rwlock_unlock(&bidib_state_boards_rwlock); + } else { + ++bidib_state_boards_rwlock_lockedcount; + } + + usleep(10000); // 0.01s (1/100th) + + // Report the mutex statistics every 2 seconds + if (iters == 200) { + printf("Libbidib: Mutex statistics report for last 2 seconds:\n"); + printf("bidib_state_trains_rwlock: Write-Locked %f percent of the time\n", + ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); + printf("trackstate_accessories_mutex: Locked %f percent of the time\n", + ((float) trackstate_accessories_mutex_lockedcount / (float) iters)*100.0f); + printf("trackstate_peripherals_mutex: Locked %f percent of the time\n", + ((float) trackstate_peripherals_mutex_lockedcount / (float) iters)*100.0f); + printf("trackstate_segments_mutex: Locked %f percent of the time\n", + ((float) trackstate_segments_mutex_lockedcount / (float) iters)*100.0f); + printf("trackstate_reversers_mutex: Locked %f percent of the time\n", + ((float) trackstate_reversers_mutex_lockedcount / (float) iters)*100.0f); + printf("trackstate_trains_mutex: Locked %f percent of the time\n", + ((float) trackstate_trains_mutex_lockedcount / (float) iters)*100.0f); + printf("trackstate_boosters_mutex: Locked %f percent of the time\n", + ((float) trackstate_boosters_mutex_lockedcount / (float) iters)*100.0f); + printf("trackstate_track_outputs_mutex: Locked %f percent of the time\n", + ((float) trackstate_track_outputs_mutex_lockedcount / (float) iters)*100.0f); + printf("bidib_state_boards_rwlock: Write-Locked %f percent of the time\n", + ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); + iters = 0; + trackstate_accessories_mutex_lockedcount = 0; + trackstate_peripherals_mutex_lockedcount = 0; + trackstate_segments_mutex_lockedcount = 0; + trackstate_reversers_mutex_lockedcount = 0; + trackstate_trains_mutex_lockedcount = 0; + trackstate_boosters_mutex_lockedcount = 0; + trackstate_track_outputs_mutex_lockedcount = 0; + } + } + + ///TODO: stopping -> report the remainder + + return NULL; } \ No newline at end of file diff --git a/test/physical/test_common.c b/test/physical/test_common.c index da81599..2e9889a 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -236,8 +236,8 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); - printf("libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", - train, segment, speed, tv.tv_sec, tv.tv_nsec); + //printf("libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", + // train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } } @@ -249,8 +249,8 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); - printf("libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", - train, segment, speed, tv.tv_sec, tv.tv_nsec); + //printf("libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", + // train, segment, speed, tv.tv_sec, tv.tv_nsec); } usleep(TRAIN_WAITING_TIME_US); From d5b0bce4995098e4099d9245e3f9ca836c055aaa Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 11:32:31 +0100 Subject: [PATCH 25/51] debug log refined --- src/highlevel/bidib_highlevel_util.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 899d448..13359ef 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -343,29 +343,31 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { ++bidib_state_boards_rwlock_lockedcount; } - usleep(10000); // 0.01s (1/100th) + usleep(5000); // 0.005s (1/100th) + //usleep(10000); // 0.01s (1/100th) // Report the mutex statistics every 2 seconds - if (iters == 200) { + if (iters == 400) { printf("Libbidib: Mutex statistics report for last 2 seconds:\n"); - printf("bidib_state_trains_rwlock: Write-Locked %f percent of the time\n", + printf("bidib_state_trains_rwlock: Write-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); - printf("trackstate_accessories_mutex: Locked %f percent of the time\n", + printf("trackstate_accessories_mutex: Locked %.2f percent of the time\n", ((float) trackstate_accessories_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_peripherals_mutex: Locked %f percent of the time\n", + printf("trackstate_peripherals_mutex: Locked %.2f percent of the time\n", ((float) trackstate_peripherals_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_segments_mutex: Locked %f percent of the time\n", + printf("trackstate_segments_mutex: Locked %.2f percent of the time\n", ((float) trackstate_segments_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_reversers_mutex: Locked %f percent of the time\n", + printf("trackstate_reversers_mutex: Locked %.2f percent of the time\n", ((float) trackstate_reversers_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_trains_mutex: Locked %f percent of the time\n", + printf("trackstate_trains_mutex: Locked %.2f percent of the time\n", ((float) trackstate_trains_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_boosters_mutex: Locked %f percent of the time\n", + printf("trackstate_boosters_mutex: Locked %.2f percent of the time\n", ((float) trackstate_boosters_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_track_outputs_mutex: Locked %f percent of the time\n", + printf("trackstate_track_outputs_mutex: Locked %.2f percent of the time\n", ((float) trackstate_track_outputs_mutex_lockedcount / (float) iters)*100.0f); - printf("bidib_state_boards_rwlock: Write-Locked %f percent of the time\n", + printf("bidib_state_boards_rwlock: Write-Locked %.2f percent of the time\n", ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); + printf("\n\n"); iters = 0; trackstate_accessories_mutex_lockedcount = 0; trackstate_peripherals_mutex_lockedcount = 0; From 00a36382706e41d526a2454afa1a97d8172aafd5 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 11:33:36 +0100 Subject: [PATCH 26/51] align debug log --- src/highlevel/bidib_highlevel_util.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 13359ef..f98708b 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -349,23 +349,23 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { // Report the mutex statistics every 2 seconds if (iters == 400) { printf("Libbidib: Mutex statistics report for last 2 seconds:\n"); - printf("bidib_state_trains_rwlock: Write-Locked %.2f percent of the time\n", + printf("bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); - printf("trackstate_accessories_mutex: Locked %.2f percent of the time\n", + printf("trackstate_accessories_mutex: Locked %.2f percent of the time\n", ((float) trackstate_accessories_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_peripherals_mutex: Locked %.2f percent of the time\n", + printf("trackstate_peripherals_mutex: Locked %.2f percent of the time\n", ((float) trackstate_peripherals_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_segments_mutex: Locked %.2f percent of the time\n", + printf("trackstate_segments_mutex: Locked %.2f percent of the time\n", ((float) trackstate_segments_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_reversers_mutex: Locked %.2f percent of the time\n", + printf("trackstate_reversers_mutex: Locked %.2f percent of the time\n", ((float) trackstate_reversers_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_trains_mutex: Locked %.2f percent of the time\n", + printf("trackstate_trains_mutex: Locked %.2f percent of the time\n", ((float) trackstate_trains_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_boosters_mutex: Locked %.2f percent of the time\n", + printf("trackstate_boosters_mutex: Locked %.2f percent of the time\n", ((float) trackstate_boosters_mutex_lockedcount / (float) iters)*100.0f); printf("trackstate_track_outputs_mutex: Locked %.2f percent of the time\n", ((float) trackstate_track_outputs_mutex_lockedcount / (float) iters)*100.0f); - printf("bidib_state_boards_rwlock: Write-Locked %.2f percent of the time\n", + printf("bidib_state_boards_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); printf("\n\n"); iters = 0; From 45c86b7e4511adf448286bcc0ac253581778f002 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:05:38 +0100 Subject: [PATCH 27/51] log for long flush --- src/transmission/bidib_transmission_receive.c | 6 +++--- src/transmission/bidib_transmission_send.c | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 001f641..94814b5 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -741,9 +741,9 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) syslog_libbidib(LOG_WARNING, "bidib_split_packet took longer than threshold %llu us for message of type %s", slow_processing_threshold_us, bidib_message_string_mapping[type]); - syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us\n", msg_read_in_us); - syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us\n", node_update_us); - syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us\n", handle_receive_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us", msg_read_in_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us", node_update_us); + syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us", handle_receive_us); } } } diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index eb86430..8002ea3 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -122,6 +122,9 @@ static void bidib_flush_impl_old(void) { * */ static void bidib_flush_impl(void) { + struct timespec start, end1, end2; + + clock_gettime(CLOCK_MONOTONIC_RAW, &start); if (buffer_index > 0) { uint8_t crc = 0; int32_t aux_index = 0; @@ -164,7 +167,17 @@ static void bidib_flush_impl(void) { buffer_index = 0; } + clock_gettime(CLOCK_MONOTONIC_RAW, &end1); syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); + clock_gettime(CLOCK_MONOTONIC_RAW, &end2); + uint64_t flush_us = (end1.tv_sec - start.tv_sec) * 1000000 + (end1.tv_nsec - start.tv_nsec) / 1000; + uint64_t log_us = (end2.tv_sec - end1.tv_sec) * 1000000 + (end2.tv_nsec - end1.tv_nsec) / 1000; + // longer than 0.01s + if (flush_us + log_us > 10000) { + syslog_libbidib(LOG_WARNING, "bidib_flush_impl took longer than 10000 us"); + syslog_libbidib(LOG_WARNING, " Flushing took %llu us", flush_us); + syslog_libbidib(LOG_WARNING, "Logging debug took %llu us", log_us); + } } void bidib_flush(void) { From 980c65b2e53b2e1387ac5bc299348b16d7a2d609 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:08:48 +0100 Subject: [PATCH 28/51] log freq changes for test driveto and level --- src/transmission/bidib_transmission_receive.c | 2 +- test/physical/test_common.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 94814b5..165b734 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -738,7 +738,7 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) if (msg_read_in_us + node_update_us + handle_receive_us > slow_processing_threshold_us) { // In case the processing steps above take above the specified threshold, // i.e., longer than expected, log the time taken for each of the three steps. - syslog_libbidib(LOG_WARNING, + syslog_libbidib(LOG_ERR, "bidib_split_packet took longer than threshold %llu us for message of type %s", slow_processing_threshold_us, bidib_message_string_mapping[type]); syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us", msg_read_in_us); diff --git a/test/physical/test_common.c b/test/physical/test_common.c index 2e9889a..d04e7eb 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -201,7 +201,7 @@ void testsuite_driveTo_old(const char *segment, int speed, const char *train) { } bidib_free_train_position_query(trainPosition); - if (counter++ % 4 == 0) { + if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); syslog(LOG_WARNING, @@ -243,7 +243,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { } bidib_free_segment_state_query(seg_query); - if (counter++ % 4 == 0) { + if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); syslog(LOG_WARNING, From 5e3fe3ce55ee39487d195ead89ecc97192b8ba4c Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:11:38 +0100 Subject: [PATCH 29/51] fix missing lock count reset for heartbeat logger --- src/highlevel/bidib_highlevel_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index f98708b..eb17f63 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -369,6 +369,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); printf("\n\n"); iters = 0; + bidib_state_trains_rwlock_lockedcount = 0; trackstate_accessories_mutex_lockedcount = 0; trackstate_peripherals_mutex_lockedcount = 0; trackstate_segments_mutex_lockedcount = 0; @@ -376,6 +377,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { trackstate_trains_mutex_lockedcount = 0; trackstate_boosters_mutex_lockedcount = 0; trackstate_track_outputs_mutex_lockedcount = 0; + bidib_state_boards_rwlock_lockedcount = 0; } } From d49c97878f9ee1fc5f10632bff1fa06d8c5ffae3 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:23:12 +0100 Subject: [PATCH 30/51] adjust debug logs --- src/highlevel/bidib_highlevel_util.c | 23 +++++++++++++++++++++++ test/physical/test_common.c | 12 ++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index eb17f63..872cfcb 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -348,6 +348,28 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { // Report the mutex statistics every 2 seconds if (iters == 400) { + syslog_libbidib(LOG_WARNING, "Mutex statistics report for last 2 seconds:\n"); + syslog_libbidib(LOG_WARNING, "bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", + ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_accessories_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_accessories_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_peripherals_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_peripherals_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_segments_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_segments_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_reversers_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_reversers_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_trains_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_trains_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_boosters_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_boosters_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "trackstate_track_outputs_mutex: Locked %.2f percent of the time\n", + ((float) trackstate_track_outputs_mutex_lockedcount / (float) iters)*100.0f); + syslog_libbidib(LOG_WARNING, "bidib_state_boards_rwlock: Wr-Locked %.2f percent of the time\n", + ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); + //printf("\n\n"); + + /* printf("Libbidib: Mutex statistics report for last 2 seconds:\n"); printf("bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); @@ -368,6 +390,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { printf("bidib_state_boards_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); printf("\n\n"); + */ iters = 0; bidib_state_trains_rwlock_lockedcount = 0; trackstate_accessories_mutex_lockedcount = 0; diff --git a/test/physical/test_common.c b/test/physical/test_common.c index d04e7eb..4b218a1 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -236,8 +236,8 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); - //printf("libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", - // train, segment, speed, tv.tv_sec, tv.tv_nsec); + printf("libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", + train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } } @@ -246,11 +246,11 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - syslog(LOG_WARNING, - "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", - train, segment, speed, tv.tv_sec, tv.tv_nsec); - //printf("libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", + //syslog(LOG_WARNING, + // "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", // train, segment, speed, tv.tv_sec, tv.tv_nsec); + printf("libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", + train, segment, speed, tv.tv_sec, tv.tv_nsec); } usleep(TRAIN_WAITING_TIME_US); From 13e6571274e77dd35a338d2c5d1d0b1af204f96c Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:35:34 +0100 Subject: [PATCH 31/51] debug time boost diagnostic --- src/highlevel/bidib_highlevel_util.c | 4 ++-- src/state/bidib_state_setter.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 872cfcb..60bcec3 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -369,7 +369,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); //printf("\n\n"); - /* + /**/ printf("Libbidib: Mutex statistics report for last 2 seconds:\n"); printf("bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); @@ -390,7 +390,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { printf("bidib_state_boards_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); printf("\n\n"); - */ + /**/ iters = 0; bidib_state_trains_rwlock_lockedcount = 0; trackstate_accessories_mutex_lockedcount = 0; diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index e4bb356..255ab38 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -971,7 +971,11 @@ void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t len const uint8_t *const diag_list, unsigned int action_id) { //pthread_rwlock_wrlock(&bidib_state_track_rwlock); // For bidib_state_get_booster_state_ref_by_nodeaddr + struct timespec start, middle, end; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); + pthread_mutex_lock(&trackstate_boosters_mutex); + clock_gettime(CLOCK_MONOTONIC_RAW, &middle); t_bidib_booster_state *booster_state = bidib_state_get_booster_state_ref_by_nodeaddr(node_address); if (booster_state != NULL) { @@ -1046,4 +1050,14 @@ void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t len } //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_boosters_mutex); + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + + uint64_t lock_acq_us = (middle.tv_sec - start.tv_sec) * 1000000 + (middle.tv_nsec - start.tv_nsec) / 1000; + uint64_t rest_us = (end.tv_sec - middle.tv_sec) * 1000000 + (end.tv_nsec - middle.tv_nsec) / 1000; + // longer than 0.01s + if (lock_acq_us + rest_us > 10000) { + syslog_libbidib(LOG_WARNING, "bidib_state_boost_diagnostic took longer than 10000 us"); + syslog_libbidib(LOG_WARNING, " Acquiring the lock took %llu us", lock_acq_us); + syslog_libbidib(LOG_WARNING, "Getting the board and rest took %llu us", rest_us); + } } From 2c24bb4fdee898585b5c0825a6186a7b8e15b6c5 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:48:23 +0100 Subject: [PATCH 32/51] heartbeat debug --- src/highlevel/bidib_highlevel_util.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 60bcec3..ab0e855 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -279,6 +279,9 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { uint32_t trackstate_track_outputs_mutex_lockedcount = 0; uint32_t bidib_state_boards_rwlock_lockedcount = 0; + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); + while (bidib_running) { //sleep(2); //struct timespec tv; @@ -348,7 +351,11 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { // Report the mutex statistics every 2 seconds if (iters == 400) { - syslog_libbidib(LOG_WARNING, "Mutex statistics report for last 2 seconds:\n"); + clock_gettime(CLOCK_MONOTONIC_RAW, &end); + uint64_t elapsed_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + + syslog_libbidib(LOG_WARNING, "Mutex statistics report for last 2 seconds (actual elapsed time: %llu, rounded to seconds: %llu):\n", + elapsed_us, elapsed_us / 1000000); syslog_libbidib(LOG_WARNING, "bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); syslog_libbidib(LOG_WARNING, "trackstate_accessories_mutex: Locked %.2f percent of the time\n", @@ -370,7 +377,8 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { //printf("\n\n"); /**/ - printf("Libbidib: Mutex statistics report for last 2 seconds:\n"); + printf("Libbidib: Mutex statistics report for last 2 seconds (actual elapsed time: %lu, rounded to seconds: %lu):\n", + elapsed_us, elapsed_us / 1000000); printf("bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); printf("trackstate_accessories_mutex: Locked %.2f percent of the time\n", @@ -401,6 +409,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { trackstate_boosters_mutex_lockedcount = 0; trackstate_track_outputs_mutex_lockedcount = 0; bidib_state_boards_rwlock_lockedcount = 0; + clock_gettime(CLOCK_MONOTONIC_RAW, &start); } } From 8bf7fec33e11dfd81ab03c71c63a146629f3a9e4 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Fri, 29 Nov 2024 12:52:20 +0100 Subject: [PATCH 33/51] fix format spec --- src/highlevel/bidib_highlevel_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index ab0e855..4950a62 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -377,7 +377,7 @@ void *bidib_heartbeat_log(void *par __attribute__((unused))) { //printf("\n\n"); /**/ - printf("Libbidib: Mutex statistics report for last 2 seconds (actual elapsed time: %lu, rounded to seconds: %lu):\n", + printf("Libbidib: Mutex statistics report for last 2 seconds (actual elapsed time: %llu, rounded to seconds: %llu):\n", elapsed_us, elapsed_us / 1000000); printf("bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); From ffed1ab992c8c348d6515ef2e4d071196c7235cf Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 10:53:22 +0100 Subject: [PATCH 34/51] Adress Part of req. changes, mostly docs and some syslog usage --- include/highlevel/bidib_highlevel_util.h | 2 ++ src/highlevel/bidib_highlevel_intern.h | 4 ++-- src/highlevel/bidib_highlevel_setter.c | 2 +- src/highlevel/bidib_highlevel_util.c | 4 ++-- src/lowlevel/bidib_lowlevel_accessory.c | 2 +- src/lowlevel/bidib_lowlevel_intern.h | 2 +- src/lowlevel/bidib_lowlevel_occupancy.c | 2 +- src/lowlevel/bidib_lowlevel_userconfig.c | 2 +- src/parser/bidib_config_parser_board.c | 2 +- src/parser/bidib_config_parser_track.c | 2 +- src/parser/bidib_config_parser_train.c | 2 +- src/transmission/bidib_transmission_intern.h | 8 +++++--- .../bidib_transmission_node_states.c | 2 +- src/transmission/bidib_transmission_receive.c | 16 ++++++++-------- src/transmission/bidib_transmission_send.c | 10 +++++----- .../bidib_transmission_serial_port.c | 12 ++++++------ 16 files changed, 39 insertions(+), 35 deletions(-) diff --git a/include/highlevel/bidib_highlevel_util.h b/include/highlevel/bidib_highlevel_util.h index ef1e1b8..8dbca7d 100644 --- a/include/highlevel/bidib_highlevel_util.h +++ b/include/highlevel/bidib_highlevel_util.h @@ -44,6 +44,8 @@ * BiDiB interface. This function must not be blocking. * @param write a pointer to a function, which sends a byte to the connected * BiDiB interface. + * @param write_n a pointer to a function, which sends n bytes to the connected + * BiDiB interface. * @param config_dir the directory in which the config files are stored, use * NULL if no configs should be used. * @param flush_interval the interval for automatic flushing in ms. If 0, diff --git a/src/highlevel/bidib_highlevel_intern.h b/src/highlevel/bidib_highlevel_intern.h index f723984..889b731 100644 --- a/src/highlevel/bidib_highlevel_intern.h +++ b/src/highlevel/bidib_highlevel_intern.h @@ -69,8 +69,8 @@ t_bidib_train_position_query bidib_get_train_position_intern(const char *train); /** * To be run in separate thread; when bidib is running, - * prints a heartbeat message with a timestep in - * a 2-second interval. + * logs a heartbeat message with a timestep in + * a 2-second interval to syslog. * * @param __attribute__ unused * @return void* diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index 1a1dac3..bacbd71 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -363,7 +363,7 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { * * @param train the id/name of the train whose speed to set * @param speed the speed to set - * @param track_output for which track output shall the speed of the train be set? + * @param track_output for which track output shall the speed of the train be set * @return int 0 if successful, 1 otherwise. */ int bidib_set_train_speed_internal(const char *train, int speed, const char *track_output){ diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 4950a62..09216c3 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -149,7 +149,7 @@ int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), bidib_discard_rx = false; } openlog("swtbahn", 0, LOG_LOCAL0); - syslog_libbidib(LOG_NOTICE, "%s", "libbidib started"); + syslog_libbidib(LOG_NOTICE, "libbidib started"); bidib_node_state_table_init(); bidib_init_rwlocks(); @@ -190,7 +190,7 @@ int bidib_start_serial(const char *device, const char *config_dir, unsigned int bidib_discard_rx = false; } openlog("swtbahn", 0, LOG_LOCAL0); - syslog_libbidib(LOG_NOTICE, "%s", "libbidib started"); + syslog_libbidib(LOG_NOTICE, "libbidib started"); bidib_node_state_table_init(); diff --git a/src/lowlevel/bidib_lowlevel_accessory.c b/src/lowlevel/bidib_lowlevel_accessory.c index 0e0bf53..7fd02c7 100644 --- a/src/lowlevel/bidib_lowlevel_accessory.c +++ b/src/lowlevel/bidib_lowlevel_accessory.c @@ -112,7 +112,7 @@ void bidib_send_accessory_para_set_macromap(t_bidib_node_address node_address, u "called with invalid parameter data_size = %02x", data_size); return; } else if (data[data_size - 1] != 0xFF) { - syslog_libbidib(LOG_ERR, "%s", + syslog_libbidib(LOG_ERR, "MSG_ACCESSORY_PARA_SET (BIDIB_ACCESSORY_PARA_MACROMAP) " "called with invalid parameter data, last byte != 0xFF"); return; diff --git a/src/lowlevel/bidib_lowlevel_intern.h b/src/lowlevel/bidib_lowlevel_intern.h index 587c9c7..610a9b9 100644 --- a/src/lowlevel/bidib_lowlevel_intern.h +++ b/src/lowlevel/bidib_lowlevel_intern.h @@ -36,7 +36,7 @@ /** * Used to avoid the usage of a recursive rwlock. - * Must call with param `lock` false if bidib_state_trains_rwlock + * Shall be called with param `lock` = false if bidib_state_trains_rwlock * has already been acquired with >= read. * * @param node_address the three bytes on top of the address stack. diff --git a/src/lowlevel/bidib_lowlevel_occupancy.c b/src/lowlevel/bidib_lowlevel_occupancy.c index 113ce76..33f4a0e 100644 --- a/src/lowlevel/bidib_lowlevel_occupancy.c +++ b/src/lowlevel/bidib_lowlevel_occupancy.c @@ -102,7 +102,7 @@ void bidib_send_bm_mirror_free(t_bidib_node_address node_address, void bidib_send_bm_addr_get_range(t_bidib_node_address node_address, uint8_t start, uint8_t end, unsigned int action_id) { if (start > end) { - syslog_libbidib(LOG_ERR, "%s", + syslog_libbidib(LOG_ERR, "MSG_BM_ADDR_GET_RANGE called with invalid parameters, start > end."); return; } diff --git a/src/lowlevel/bidib_lowlevel_userconfig.c b/src/lowlevel/bidib_lowlevel_userconfig.c index db409df..6cb8270 100644 --- a/src/lowlevel/bidib_lowlevel_userconfig.c +++ b/src/lowlevel/bidib_lowlevel_userconfig.c @@ -56,7 +56,7 @@ void bidib_send_vendor_disable(t_bidib_node_address node_address, unsigned int a void bidib_send_vendor_set(t_bidib_node_address node_address, t_bidib_vendor_data vendor_data, unsigned int action_id) { if (vendor_data.name_length + vendor_data.value_length > 119) { - syslog_libbidib(LOG_ERR, "%s", + syslog_libbidib(LOG_ERR, "MSG_VENDOR_SET called with invalid parameter vendor_data, " "message too long (max message length is 127 bytes"); return; diff --git a/src/parser/bidib_config_parser_board.c b/src/parser/bidib_config_parser_board.c index 0ca5a0a..640585c 100644 --- a/src/parser/bidib_config_parser_board.c +++ b/src/parser/bidib_config_parser_board.c @@ -282,7 +282,7 @@ int bidib_config_parse_board_config(const char *config_dir) { bidib_config_parse_single_board_features); if (error) { - syslog_libbidib(LOG_ERR, "%s", "Error while parsing board config"); + syslog_libbidib(LOG_ERR, "Error while parsing board config"); } yaml_parser_delete(&parser); diff --git a/src/parser/bidib_config_parser_track.c b/src/parser/bidib_config_parser_track.c index ce623e9..0b9c671 100644 --- a/src/parser/bidib_config_parser_track.c +++ b/src/parser/bidib_config_parser_track.c @@ -1666,7 +1666,7 @@ int bidib_config_parse_track_config(const char *config_dir) { &parser, "boards", bidib_config_parse_single_board_setup); if (error) { - syslog_libbidib(LOG_ERR, "%s", "Error while parsing track config"); + syslog_libbidib(LOG_ERR, "Error while parsing track config"); } yaml_parser_delete(&parser); diff --git a/src/parser/bidib_config_parser_train.c b/src/parser/bidib_config_parser_train.c index 32e8007..ece2a82 100644 --- a/src/parser/bidib_config_parser_train.c +++ b/src/parser/bidib_config_parser_train.c @@ -487,7 +487,7 @@ int bidib_config_parse_train_config(const char *config_dir) { bidib_config_parse_single_train); if (error) { - syslog_libbidib(LOG_ERR, "%s", "Error while parsing train config"); + syslog_libbidib(LOG_ERR, "Error while parsing train config"); } yaml_parser_delete(&parser); diff --git a/src/transmission/bidib_transmission_intern.h b/src/transmission/bidib_transmission_intern.h index f78aba7..8719a9b 100644 --- a/src/transmission/bidib_transmission_intern.h +++ b/src/transmission/bidib_transmission_intern.h @@ -229,7 +229,8 @@ uint8_t *bidib_read_intern_message(void); void bidib_set_read_src(uint8_t (*read)(int *)); /** - * Sets the output of libbidib. + * Sets the output of libbidib, specifically the output + * which allows writing a single byte at a time. * * @param write a pointer to a function, which sends a byte to the connected * BiDiB interface. @@ -237,9 +238,10 @@ void bidib_set_read_src(uint8_t (*read)(int *)); void bidib_set_write_dest(void (*write)(uint8_t)); /** - * Sets the output of libbidib. + * Sets the output of libbidib, specifically the output + * which allows writing n bytes at a time. * - * @param write_n a pointer to a function, which sends multiple bytes to the connected + * @param write_n a pointer to a function, which sends n bytes to the connected * BiDiB interface. */ void bidib_set_write_n_dest(void (*write_n)(uint8_t*, int32_t)); diff --git a/src/transmission/bidib_transmission_node_states.c b/src/transmission/bidib_transmission_node_states.c index e459aca..acd7248 100644 --- a/src/transmission/bidib_transmission_node_states.c +++ b/src/transmission/bidib_transmission_node_states.c @@ -319,5 +319,5 @@ void bidib_node_state_table_free(void) { g_hash_table_destroy(node_state_table); } pthread_mutex_unlock(&bidib_node_state_table_mutex); - syslog_libbidib(LOG_INFO, "%s", "Node state table freed"); + syslog_libbidib(LOG_INFO, "Node state table freed"); } diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 165b734..cde4e89 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -65,7 +65,7 @@ void bidib_set_read_src(uint8_t (*read)(int *)) { uplink_error_queue = g_queue_new(); uplink_intern_queue = g_queue_new(); read_byte = read; - syslog_libbidib(LOG_INFO, "%s", "Read function was set"); + syslog_libbidib(LOG_INFO, "Read function was set"); } void bidib_set_lowlevel_debug_mode(bool uplink_debug_mode_on) { @@ -99,7 +99,7 @@ void bidib_uplink_queue_reset(bool lock_mutex) { if (lock_mutex) { pthread_mutex_unlock(&bidib_uplink_queue_mutex); } - syslog_libbidib(LOG_INFO, "%s", "Message queue reset"); + syslog_libbidib(LOG_INFO, "Message queue reset"); } void bidib_uplink_queue_free(void) { @@ -110,7 +110,7 @@ void bidib_uplink_queue_free(void) { g_queue_free(uplink_queue); } pthread_mutex_unlock(&bidib_uplink_queue_mutex); - syslog_libbidib(LOG_INFO, "%s", "Message queue freed"); + syslog_libbidib(LOG_INFO, "Message queue freed"); } } @@ -124,7 +124,7 @@ void bidib_uplink_error_queue_reset(bool lock_mutex) { if (lock_mutex) { pthread_mutex_unlock(&bidib_uplink_error_queue_mutex); } - syslog_libbidib(LOG_INFO, "%s", "Error message queue reset"); + syslog_libbidib(LOG_INFO, "Error message queue reset"); } void bidib_uplink_error_queue_free(void) { @@ -135,7 +135,7 @@ void bidib_uplink_error_queue_free(void) { g_queue_free(uplink_error_queue); } pthread_mutex_unlock(&bidib_uplink_error_queue_mutex); - syslog_libbidib(LOG_INFO, "%s", "Error message queue freed"); + syslog_libbidib(LOG_INFO, "Error message queue freed"); } } @@ -149,7 +149,7 @@ void bidib_uplink_intern_queue_reset(bool lock_mutex) { if (lock_mutex) { pthread_mutex_unlock(&bidib_uplink_intern_queue_mutex); } - syslog_libbidib(LOG_INFO, "%s", "Intern message queue reset"); + syslog_libbidib(LOG_INFO, "Intern message queue reset"); } void bidib_uplink_intern_queue_free(void) { @@ -160,7 +160,7 @@ void bidib_uplink_intern_queue_free(void) { g_queue_free(uplink_intern_queue); } pthread_mutex_unlock(&bidib_uplink_intern_queue_mutex); - syslog_libbidib(LOG_INFO, "%s", "Intern message queue freed"); + syslog_libbidib(LOG_INFO, "Intern message queue freed"); } } @@ -801,7 +801,7 @@ static void bidib_receive_packet(void) { buffer_index--; bidib_split_packet(buffer, buffer_index); } else { - syslog_libbidib(LOG_ERR, "%s", "CRC wrong, packet ignored"); + syslog_libbidib(LOG_ERR, "CRC wrong, packet ignored"); } } diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 8002ea3..77130f0 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -54,12 +54,12 @@ static volatile size_t buffer_index = 0; void bidib_set_write_dest(void (*write)(uint8_t)) { write_byte = write; - syslog_libbidib(LOG_INFO, "%s", "Write function was set"); + syslog_libbidib(LOG_INFO, "Write function was set"); } void bidib_set_write_n_dest(void (*write_n)(uint8_t*, int32_t)) { write_bytes = write_n; - syslog_libbidib(LOG_INFO, "%s", "Write_n function was set"); + syslog_libbidib(LOG_INFO, "Write_n function was set"); } void bidib_state_packet_capacity(uint8_t max_capacity) { @@ -102,11 +102,11 @@ static void bidib_flush_impl_old(void) { // start-delimiter for next one buffer_index = 0; } - syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); + syslog_libbidib(LOG_DEBUG, "Cache flushed"); } /** - * Will flush the send cache, if possible in once go (as one batch); + * Will flush the send cache, if possible in one go (as one batch); * if batching not possible, then send byte-per-byte. * Shall only be called with bidib_send_buffer_mutex locked. * @@ -168,7 +168,7 @@ static void bidib_flush_impl(void) { buffer_index = 0; } clock_gettime(CLOCK_MONOTONIC_RAW, &end1); - syslog_libbidib(LOG_DEBUG, "%s", "Cache flushed"); + syslog_libbidib(LOG_DEBUG, "Cache flushed"); clock_gettime(CLOCK_MONOTONIC_RAW, &end2); uint64_t flush_us = (end1.tv_sec - start.tv_sec) * 1000000 + (end1.tv_nsec - start.tv_nsec) / 1000; uint64_t log_us = (end2.tv_sec - end1.tv_sec) * 1000000 + (end2.tv_nsec - end1.tv_nsec) / 1000; diff --git a/src/transmission/bidib_transmission_serial_port.c b/src/transmission/bidib_transmission_serial_port.c index 1816253..a6cdc46 100644 --- a/src/transmission/bidib_transmission_serial_port.c +++ b/src/transmission/bidib_transmission_serial_port.c @@ -89,7 +89,7 @@ int bidib_detect_baudrate(void) { syslog_libbidib(LOG_INFO, "Trying baud rate 19200"); bidib_serial_port_set_options(B19200); } else if (remaining_tries == 0) { - syslog_libbidib(LOG_ERR, "%s", "Couldn't find working baud rate"); + syslog_libbidib(LOG_ERR, "Couldn't find working baud rate"); return 1; } } @@ -100,7 +100,7 @@ int bidib_detect_baudrate(void) { int bidib_serial_port_init(const char *device) { fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK | O_SYNC); if (fd < 0) { - syslog_libbidib(LOG_ERR, "%s", "Error while opening serial port"); + syslog_libbidib(LOG_ERR, "Error while opening serial port"); return 1; } else { #ifndef __APPLE__ @@ -108,7 +108,7 @@ int bidib_serial_port_init(const char *device) { #else bidib_serial_port_set_options(B115200); #endif - syslog_libbidib(LOG_INFO, "%s", "Serial port opened"); + syslog_libbidib(LOG_INFO, "Serial port opened"); return 0; } } @@ -120,13 +120,13 @@ uint8_t bidib_serial_port_read(int *byte_read) { void bidib_serial_port_write(uint8_t msg) { if (write(fd, &msg, 1) != 1) { - syslog_libbidib(LOG_ERR, "%s", "Error while sending data via serial port (single byte write)"); + syslog_libbidib(LOG_ERR, "Error while sending data via serial port (single byte write)"); } } void bidib_serial_port_write_n(uint8_t *msg, int32_t len) { if (msg == NULL || len <= 0 || (write(fd, msg, len) != len)) { - syslog_libbidib(LOG_ERR, "Error while sending data via serial port (multi byte write)"); + syslog_libbidib(LOG_ERR, "Error while sending data via serial port (%d-byte write)", len); } } @@ -134,6 +134,6 @@ void bidib_serial_port_close(void) { if (fd != 0) { close(fd); fd = 0; - syslog_libbidib(LOG_INFO, "%s", "Serial port closed"); + syslog_libbidib(LOG_INFO, "Serial port closed"); } } From 0bdc37586b53d13446e938533fc51755fdb25f09 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 10:56:39 +0100 Subject: [PATCH 35/51] remove all "Old: ..." in function docs --- src/lowlevel/bidib_lowlevel_intern.h | 3 --- src/state/bidib_state_getter_intern.h | 25 ------------------------- src/state/bidib_state_intern.h | 3 --- src/state/bidib_state_setter_intern.h | 9 --------- 4 files changed, 40 deletions(-) diff --git a/src/lowlevel/bidib_lowlevel_intern.h b/src/lowlevel/bidib_lowlevel_intern.h index 610a9b9..5f76f67 100644 --- a/src/lowlevel/bidib_lowlevel_intern.h +++ b/src/lowlevel/bidib_lowlevel_intern.h @@ -53,9 +53,6 @@ void bidib_send_cs_drive_intern(t_bidib_node_address node_address, * Issues an accessory command. * Shall only be called with trackstate_accessories_mutex acquired, * and with bidib_state_boards_rwlock >=read acquired. - * - * Old: Must only be called with bidib_state_track_rwlock write acquired, - * and with bidib_state_boards_rwlock >=read acquired. * * @param node_address the three bytes on top of the address stack. * @param cs_accessory_params the parameters. diff --git a/src/state/bidib_state_getter_intern.h b/src/state/bidib_state_getter_intern.h index 3fc7fd3..48010bc 100644 --- a/src/state/bidib_state_getter_intern.h +++ b/src/state/bidib_state_getter_intern.h @@ -56,8 +56,6 @@ t_bidib_board *bidib_state_get_board_ref_by_uniqueid(t_bidib_unique_id_mod uniqu /** * Returns the reference to the booster state with the given id. * Shall only be called with trackstate_boosters_mutex acquired. - * - * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param booster the id of the booster. * @return NULL if not found, otherwise the reference to the booster state. @@ -67,8 +65,6 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref(const char *booster); /** * Returns the reference to the track output state with the given id. * Shall only be called with trackstate_track_outputs_mutex acquired. - * - * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param track_output the id of the track output state. * @return NULL if not found, otherwise the reference to the track output state. @@ -102,8 +98,6 @@ t_bidib_board_accessory_mapping *bidib_state_get_board_accessory_mapping_ref_by_ /** * Returns the reference to the board accessory state with the given id. * Shall only be called with trackstate_accessories_mutex acquired. - * - * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param accessory the id of the board accessory state. * @param point whether the accessory is a point or a signal. @@ -139,8 +133,6 @@ t_bidib_dcc_accessory_mapping *bidib_state_get_dcc_accessory_mapping_ref_by_dcca /** * Returns the reference to the dcc accessory state with the given id. * Shall only be called with trackstate_accessories_mutex acquired. - * - * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param accessory the id of the dcc accessory state. * @param point whether the accessory is a point or a signal. @@ -172,8 +164,6 @@ t_bidib_peripheral_mapping *bidib_state_get_peripheral_mapping_ref_by_port( /** * Returns the reference to the peripheral state with the given id. * Shall only be called with trackstate_peripherals_mutex acquired. - * - * Old: Must only be called with the bidib_state_track_rwlock >= read acquired. * * @param peripheral the id of the peripheral. * @return NULL if not found, otherwise the reference to the peripheral state. @@ -184,8 +174,6 @@ t_bidib_peripheral_state *bidib_state_get_peripheral_state_ref(const char *perip * Returns the reference to the segment state with the given id. * Shall only be called with trackstate_segments_mutex acquired. * - * Old: Must only be called with the bidib_state_track_rwlock >= read acquired. - * * @param segment the id of the segment. * @return NULL if not found, otherwise the reference to the segment state. */ @@ -205,8 +193,6 @@ t_bidib_segment_state_intern bidib_state_get_segment_state( * Shall only be called with trackstate_segments_mutex acquired. * Note: uses bidib_state_boards_rwlock internally, so shall not be called * with bidib_state_boards_rwlock already acquired. - * - * Old: Must only be called with bidib_state_track_rwlock >= read acquired. * * @param node_address the node address of the board. * @param number the number on the board. @@ -218,8 +204,6 @@ t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( /** * Returns the reference to the reverser state with the given id. * Shall only be called with trackstate_reversers_mutex acquired. - * - * Old: Must only be called with the bidib_state_track_rwlock >= read acquired. * * @param reverser the id of the reverser. * @return NULL if not found, otherwise the reference to the reverser state. @@ -268,9 +252,6 @@ t_bidib_train *bidib_state_get_train_ref(const char *train); * Returns the reference to the train state with the given dcc address. * Shall only be called with bidib_state_trains_rwlock >= read acquired, * and with trackstate_trains_mutex acquired. - * - * Old: Must only be called with bidib_state_trains_rwlock >= read acquired - * and bidib_state_track_rwlock >= read acquired. * * @param dcc_address the dcc address of the train. * @return NULL if not found, otherwise the reference to the train state. @@ -292,8 +273,6 @@ t_bidib_train_peripheral_state *bidib_state_get_train_peripheral_state_by_bit( /** * Returns the reference to the train state with the given id. * Shall only be called with trackstate_trains_mutex acquired. - * - * Old: Must be called with bidib_state_track_rwlock >= read acquired. * * @param train the id of the train state. * @return NULL if not found, otherwise the reference to the train state. @@ -304,8 +283,6 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref(const char *train); * Returns the reference to the booster state with the given node address. * Shall only be called with trackstate_boosters_mutex acquired. * Note: uses bidib_state_boards_rwlock internally. - * - * Old: Must be called with bidib_state_track_rwlock >= read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the booster state. @@ -317,8 +294,6 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( * Returns the reference to the track output state with the given node address. * Shall only be called with trackstate_track_outputs_mutex acquired. * Note: uses bidib_state_boards_rwlock internally. - * - * Old: Must be called with bidib_state_track_rwlock >= read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the track output state. diff --git a/src/state/bidib_state_intern.h b/src/state/bidib_state_intern.h index 39bff28..001f113 100644 --- a/src/state/bidib_state_intern.h +++ b/src/state/bidib_state_intern.h @@ -472,9 +472,6 @@ void bidib_state_add_initial_train_value(t_bidib_state_train_initial_value value * Updates the available state for all trains. * Shall only be called with bidib_state_trains_rwlock >= read acquired, * and with trackstate_segments_mutex and trackstate_trains_mutex acquired. - * - * Old: Must only be called with bidib_state_trains_rwlock >=read acquired, - * and bidib_state_track_rwlock write acquired. */ void bidib_state_update_train_available(void); diff --git a/src/state/bidib_state_setter_intern.h b/src/state/bidib_state_setter_intern.h index e29d4b9..cde5ebe 100644 --- a/src/state/bidib_state_setter_intern.h +++ b/src/state/bidib_state_setter_intern.h @@ -109,9 +109,6 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, * Sets the ack info for an dcc accessory. * Shall only be called with trackstate_accessories_mutex acquired, * and bidib_state_boards_rwlock >= read lock acquired. - * - * Old: Must be called with bidib_state_track_rwlock write lock acquired, - * and bidib_state_boards_rwlock read or write lock acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -133,9 +130,6 @@ void bidib_state_cs_drive(t_bidib_cs_drive_mod params); * Sets the reported info about manual dcc accessory operation. * Shall only be called with trackstate_accessories_mutex acquired, * and with bidib_state_boards_rwlock >= read acquired. - * - * Old: Must only be called with bidib_state_track_rwlock write acquired, - * and with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -148,9 +142,6 @@ void bidib_state_cs_accessory_manual(t_bidib_node_address node_address, * Sets the new state for a dcc accessory. * Shall only be called with trackstate_accessories_mutex acquired, * and with bidib_state_boards_rwlock >= read acquired. - * - * Old: Must only be called with bidib_state_track_rwlock write acquired, - * and with bidib_state_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param params the parameters for the dcc accessory. From b07b1b64c55f1d97bc62d7d3d6b88b23c13d3ce5 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 11:22:23 +0100 Subject: [PATCH 36/51] Remove all old trackstate readwrite lock lines --- src/highlevel/bidib_highlevel_getter.c | 44 +---------- src/highlevel/bidib_highlevel_intern.h | 1 - src/highlevel/bidib_highlevel_setter.c | 33 ++------ src/highlevel/bidib_highlevel_util.c | 2 - src/lowlevel/bidib_lowlevel_track.c | 4 +- src/state/bidib_state.c | 79 ++++--------------- src/state/bidib_state_intern.h | 1 - src/state/bidib_state_setter.c | 66 +++++----------- src/transmission/bidib_transmission_receive.c | 12 +-- test/unit/bidib_highlevel_message_tests.c | 5 +- test/unit/bidib_parallel_tests.c | 4 +- 11 files changed, 50 insertions(+), 201 deletions(-) diff --git a/src/highlevel/bidib_highlevel_getter.c b/src/highlevel/bidib_highlevel_getter.c index dfebb20..7377360 100644 --- a/src/highlevel/bidib_highlevel_getter.c +++ b/src/highlevel/bidib_highlevel_getter.c @@ -209,7 +209,6 @@ static t_bidib_track_output_state *bidib_get_state_track_outputs(void) { t_bidib_track_state bidib_get_state(void) { t_bidib_track_state query = {0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL}; - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.points_board, .points_dcc, .signals_board, .signals_dcc pthread_mutex_lock(&trackstate_accessories_mutex); query.points_board_count = bidib_track_state.points_board->len; @@ -258,7 +257,6 @@ t_bidib_track_state bidib_get_state(void) { query.track_outputs = bidib_get_state_track_outputs(); pthread_mutex_unlock(&trackstate_track_outputs_mutex); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); return query; } @@ -758,7 +756,6 @@ t_bidib_id_list_query bidib_get_connected_boosters(void) { t_bidib_id_list_query bidib_get_boosters(void) { t_bidib_id_list_query query = {0, NULL}; - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.boosters pthread_mutex_lock(&trackstate_boosters_mutex); if (bidib_track_state.boosters->len > 0) { @@ -771,7 +768,6 @@ t_bidib_id_list_query bidib_get_boosters(void) { strcpy(query.ids[i], state_i.id); } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_boosters_mutex); return query; } @@ -806,7 +802,6 @@ t_bidib_id_list_query bidib_get_connected_track_outputs(void) { t_bidib_id_list_query bidib_get_track_outputs(void) { t_bidib_id_list_query query = {0, NULL}; - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.track_outputs pthread_mutex_lock(&trackstate_track_outputs_mutex); @@ -821,13 +816,11 @@ t_bidib_id_list_query bidib_get_track_outputs(void) { strcpy(query.ids[i], state_i.id); } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_track_outputs_mutex); return query; } size_t bidib_get_point_state_index(const char *point) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.points_board pthread_mutex_lock(&trackstate_accessories_mutex); for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { @@ -835,17 +828,14 @@ size_t bidib_get_point_state_index(const char *point) { bidib_track_state.points_board, t_bidib_board_accessory_state, i); if (strcmp(accessory_state->id, point) == 0) { pthread_mutex_unlock(&trackstate_accessories_mutex); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); return i; } } pthread_mutex_unlock(&trackstate_accessories_mutex); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); return -1; } size_t bidib_get_signal_state_index(const char *signal) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.signals_board pthread_mutex_lock(&trackstate_accessories_mutex); @@ -853,30 +843,25 @@ size_t bidib_get_signal_state_index(const char *signal) { const t_bidib_board_accessory_state *const accessory_state = &g_array_index( bidib_track_state.signals_board, t_bidib_board_accessory_state, i); if (strcmp(accessory_state->id, signal) == 0) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return i; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return -1; } size_t bidib_get_segment_state_index(const char *segment) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.segments pthread_mutex_lock(&trackstate_segments_mutex); for (size_t i = 0; i < bidib_track_state.segments->len; i++) { const t_bidib_segment_state_intern *const segment_state_i = &g_array_index( bidib_track_state.segments, t_bidib_segment_state_intern, i); if (!strcmp(segment_state_i->id->str, segment)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); return i; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); return -1; } @@ -887,7 +872,6 @@ t_bidib_unified_accessory_state_query bidib_get_point_state(const char *point) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_board_accessory_state_ref and bidib_state_get_dcc_accessory_state_ref pthread_mutex_lock(&trackstate_accessories_mutex); @@ -928,7 +912,6 @@ t_bidib_unified_accessory_state_query bidib_get_point_state(const char *point) { query.dcc_accessory_state.switch_time = dcc_tmp->data.switch_time; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return query; } @@ -938,7 +921,6 @@ t_bidib_unified_accessory_state_query bidib_get_signal_state(const char *signal) if (signal == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_board_accessory_state_ref and bidib_state_get_dcc_accessory_state_ref pthread_mutex_lock(&trackstate_accessories_mutex); @@ -977,7 +959,6 @@ t_bidib_unified_accessory_state_query bidib_get_signal_state(const char *signal) query.dcc_accessory_state.switch_time = dcc_tmp->data.switch_time; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return query; } @@ -988,7 +969,6 @@ t_bidib_peripheral_state_query bidib_get_peripheral_state(const char *peripheral if (peripheral == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_peripheral_state_ref pthread_mutex_lock(&trackstate_peripherals_mutex); @@ -1007,7 +987,6 @@ t_bidib_peripheral_state_query bidib_get_peripheral_state(const char *peripheral query.data.time_unit = tmp->data.time_unit; query.data.wait = tmp->data.wait; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); return query; } @@ -1019,7 +998,6 @@ t_bidib_segment_state_query bidib_get_segment_state(const char *segment) { if (segment == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_segment_state_ref pthread_mutex_lock(&trackstate_segments_mutex); @@ -1035,7 +1013,6 @@ t_bidib_segment_state_query bidib_get_segment_state(const char *segment) { memcpy(query.data.dcc_addresses, tmp->dcc_addresses->data, sizeof(t_bidib_dcc_address) * tmp->dcc_addresses->len); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); return query; } @@ -1046,7 +1023,6 @@ t_bidib_reverser_state_query bidib_get_reverser_state(const char *reverser) { if (reverser == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_reverser_state_ref pthread_mutex_lock(&trackstate_reversers_mutex); @@ -1073,7 +1049,6 @@ t_bidib_booster_state_query bidib_get_booster_state(const char *booster) { if (booster == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_booster_state_ref pthread_mutex_lock(&trackstate_boosters_mutex); @@ -1088,7 +1063,6 @@ t_bidib_booster_state_query bidib_get_booster_state(const char *booster) { query.data.temp_known = tmp->data.temp_known; query.data.temp_celsius = tmp->data.temp_celsius; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_boosters_mutex); return query; } @@ -1099,7 +1073,6 @@ t_bidib_track_output_state_query bidib_get_track_output_state(const char *track_ if (track_output == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_track_output_state_ref pthread_mutex_lock(&trackstate_track_outputs_mutex); const t_bidib_track_output_state *const tmp = @@ -1108,13 +1081,13 @@ t_bidib_track_output_state_query bidib_get_track_output_state(const char *track_ query.known = true; query.cs_state = tmp->cs_state; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_track_outputs_mutex); return query; } t_bidib_id_list_query bidib_get_trains(void) { t_bidib_id_list_query query = {0, NULL}; + // For accessing bidib_trains pthread_rwlock_rdlock(&bidib_state_trains_rwlock); if (bidib_trains->len > 0) { query.length = bidib_trains->len; @@ -1132,7 +1105,6 @@ t_bidib_id_list_query bidib_get_trains(void) { t_bidib_id_list_query bidib_get_trains_on_track(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.trains pthread_mutex_lock(&trackstate_trains_mutex); @@ -1157,13 +1129,13 @@ t_bidib_id_list_query bidib_get_trains_on_track(void) { } } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); return query; } t_bidib_id_query bidib_get_train_id(t_bidib_dcc_address dcc_address) { t_bidib_id_query query = {false, NULL}; + // For accessing bidib_trains pthread_rwlock_rdlock(&bidib_state_trains_rwlock); for (size_t i = 0; i < bidib_trains->len; i++) { const t_bidib_train *const train_i = &g_array_index(bidib_trains, t_bidib_train, i); @@ -1227,7 +1199,6 @@ t_bidib_train_state_query bidib_get_train_state(const char *train) { if (train == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_train_state_ref pthread_mutex_lock(&trackstate_trains_mutex); @@ -1253,7 +1224,6 @@ t_bidib_train_state_query bidib_get_train_state(const char *train) { } query.data.decoder_state = train_state->decoder_state; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1264,7 +1234,6 @@ t_bidib_train_peripheral_state_query bidib_get_train_peripheral_state(const char if (train == NULL || peripheral == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_train_state_ref pthread_mutex_lock(&trackstate_trains_mutex); @@ -1280,7 +1249,6 @@ t_bidib_train_peripheral_state_query bidib_get_train_peripheral_state(const char } } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1290,7 +1258,6 @@ bool bidib_get_train_on_track(const char *train) { if (train == NULL) { return res; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_train_state_ref pthread_mutex_lock(&trackstate_trains_mutex); @@ -1298,7 +1265,6 @@ bool bidib_get_train_on_track(const char *train) { if (train_state != NULL && train_state->on_track) { res = true; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); return res; } @@ -1357,13 +1323,11 @@ t_bidib_train_position_query bidib_get_train_position_intern(const char *train) t_bidib_train_position_query bidib_get_train_position(const char *train) { // All for bidib_get_train_position_intern pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); pthread_mutex_lock(&trackstate_segments_mutex); pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_position_query query = bidib_get_train_position_intern(train); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); @@ -1376,7 +1340,6 @@ t_bidib_train_speed_step_query bidib_get_train_speed_step(const char *train) { if (train == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_train_state_ref pthread_mutex_lock(&trackstate_trains_mutex); const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); @@ -1385,7 +1348,6 @@ t_bidib_train_speed_step_query bidib_get_train_speed_step(const char *train) { query.speed_step = train_state->set_speed_step; query.is_forwards = train_state->set_is_forwards; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); return query; } @@ -1395,7 +1357,6 @@ t_bidib_train_speed_kmh_query bidib_get_train_speed_kmh(const char *train) { if (train == NULL) { return query; } - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_state_get_train_state_ref pthread_mutex_lock(&trackstate_trains_mutex); const t_bidib_train_state_intern *const train_state = bidib_state_get_train_state_ref(train); @@ -1403,7 +1364,6 @@ t_bidib_train_speed_kmh_query bidib_get_train_speed_kmh(const char *train) { query.known_and_avail = true; query.speed_kmh = train_state->detected_kmh_speed; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); return query; } diff --git a/src/highlevel/bidib_highlevel_intern.h b/src/highlevel/bidib_highlevel_intern.h index 889b731..6893231 100644 --- a/src/highlevel/bidib_highlevel_intern.h +++ b/src/highlevel/bidib_highlevel_intern.h @@ -36,7 +36,6 @@ extern pthread_rwlock_t bidib_state_trains_rwlock; -//extern pthread_rwlock_t bidib_state_track_rwlock; extern pthread_rwlock_t bidib_state_boards_rwlock; extern pthread_mutex_t bidib_action_id_mutex; diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index bacbd71..472896b 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -71,8 +71,7 @@ int bidib_switch_point(const char *point, const char *aspect) { return 1; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_send_cs_accessory_intern and bidib_state_get_dcc_accessory_state_ref + // For bidib_send_cs_accessory_intern and bidib_state_get_dcc_accessory_state_ref (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); // For accessing bidib_boards and bidib_send_cs_accessory_intern @@ -91,7 +90,6 @@ int bidib_switch_point(const char *point, const char *aspect) { syslog_libbidib(LOG_ERR, "Switch point %s: board %s is not connected", point, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -115,7 +113,6 @@ int bidib_switch_point(const char *point, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } @@ -130,7 +127,6 @@ int bidib_switch_point(const char *point, const char *aspect) { syslog_libbidib(LOG_ERR, "Switch point %s: board %s is not connected", point, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -173,12 +169,10 @@ int bidib_switch_point(const char *point, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } else { pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Switch point %s: aspect %s doesn't exist", point, aspect); @@ -188,7 +182,6 @@ int bidib_switch_point(const char *point, const char *aspect) { } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Switch point %s: not found", point); return 1; @@ -200,8 +193,7 @@ int bidib_set_signal(const char *signal, const char *aspect) { return 1; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_send_cs_accessory_intern and bidib_state_get_dcc_accessory_state_ref + // For bidib_send_cs_accessory_intern and bidib_state_get_dcc_accessory_state_ref (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); // For accessing bidib_boards and bidib_send_cs_accessory_intern @@ -217,7 +209,6 @@ int bidib_set_signal(const char *signal, const char *aspect) { syslog_libbidib(LOG_ERR, "Set signal %s: board %s is not connected", signal, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -240,7 +231,6 @@ int bidib_set_signal(const char *signal, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } @@ -254,7 +244,6 @@ int bidib_set_signal(const char *signal, const char *aspect) { syslog_libbidib(LOG_ERR, "Set signal %s: board %s is not connected", signal, board_i->id->str); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -299,14 +288,12 @@ int bidib_set_signal(const char *signal, const char *aspect) { ret = 1; } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Set signal %s: not found", signal); return 1; @@ -317,6 +304,7 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { syslog_libbidib(LOG_ERR, "Set peripheral: parameters must not be NULL"); return 1; } + // For accessing bidib_boards pthread_rwlock_rdlock(&bidib_state_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); @@ -563,13 +551,10 @@ int bidib_emergency_stop_train(const char *train, const char *track_output) { } } -// Must be called with bidib_state_trains_rwlock >=read acquired and -// bidib_state_track_rwlock >=read acquired. - /** * Get the current bit(s) for the train peripherals. * Shall only be called with bidib_state_trains_rwlock >= read acquired, - * and with trackstate_trains_mutex acquired. + * and with trackstate_trains_mutex acquired. * * @param train * @param start @@ -614,7 +599,6 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ // For bidib_state_get_train_ref and bidib_send_cs_drive_intern pthread_rwlock_wrlock(&bidib_state_trains_rwlock); - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For bidib_get_current_train_peripheral_bits pthread_mutex_lock(&trackstate_trains_mutex); // For bidib_state_get_board_ref @@ -635,7 +619,6 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ track_output); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); return 1; @@ -696,7 +679,6 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ board->node_addr.sub, board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = board->node_addr; pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); pthread_rwlock_unlock(&bidib_state_trains_rwlock); @@ -704,7 +686,6 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); syslog_libbidib(LOG_ERR, "Set train peripheral: peripheral %s doesn't exist", peripheral); @@ -803,8 +784,7 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { return 1; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_reverser_state_ref + // For bidib_state_get_reverser_state_ref (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); // For bidib_state_get_board_ref and bidib_state_get_reverser_mapping_ref pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -814,7 +794,6 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { t_bidib_reverser_state *state_ref = bidib_state_get_reverser_state_ref(reverser); if (board_ref == NULL || !board_ref->connected) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Request reverser state: board %s doesn't exist or is not connected", @@ -822,7 +801,6 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { return 1; } else if (mapping_ref == NULL || state_ref == NULL) { pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Request reverser state: reverser %s does not exist", @@ -839,7 +817,6 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { (uint8_t *)mapping_ref->cv->str, 0); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); return 0; } diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 09216c3..8a8a6c3 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -53,7 +53,6 @@ static pthread_t bidib_heartbeat_thread = 0; // They do NOT protect the concurrent sending of low-level commands // to the BiDiB master node over a serial connection. pthread_rwlock_t bidib_state_trains_rwlock; -//pthread_rwlock_t bidib_state_track_rwlock; pthread_rwlock_t bidib_state_boards_rwlock; pthread_mutex_t trackstate_accessories_mutex; @@ -71,7 +70,6 @@ volatile bool bidib_lowlevel_debug_mode = false; static void bidib_init_rwlocks(void) { pthread_rwlock_init(&bidib_state_trains_rwlock, NULL); - //pthread_rwlock_init(&bidib_state_track_rwlock, NULL); pthread_rwlock_init(&bidib_state_boards_rwlock, NULL); } diff --git a/src/lowlevel/bidib_lowlevel_track.c b/src/lowlevel/bidib_lowlevel_track.c index 4f8b03b..f76e99c 100644 --- a/src/lowlevel/bidib_lowlevel_track.c +++ b/src/lowlevel/bidib_lowlevel_track.c @@ -112,15 +112,13 @@ void bidib_send_cs_accessory_intern(t_bidib_node_address node_address, void bidib_send_cs_accessory(t_bidib_node_address node_address, t_bidib_cs_accessory_mod cs_accessory_params, unsigned int action_id) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // Both for bidib_send_cs_accessory_intern + // Both for bidib_send_cs_accessory_intern (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); bidib_send_cs_accessory_intern(node_address, cs_accessory_params, action_id); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); } diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 69ee083..23d1e7f 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -473,13 +473,11 @@ bool bidib_state_add_train(t_bidib_train train) { } static bool bidib_state_point_exists(const char *id) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.points_board and .points_dcc pthread_mutex_lock(&trackstate_accessories_mutex); for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.points_board, t_bidib_board_accessory_state, i).id)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } @@ -487,24 +485,20 @@ static bool bidib_state_point_exists(const char *id) { for (size_t i = 0; i < bidib_track_state.points_dcc->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.points_dcc, t_bidib_dcc_accessory_state, i).id)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } static bool bidib_state_signal_exists(const char *id) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.signals_board, .signals_dcc pthread_mutex_lock(&trackstate_accessories_mutex); for (size_t i = 0; i < bidib_track_state.signals_board->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.signals_board, t_bidib_board_accessory_state, i).id)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } @@ -512,96 +506,79 @@ static bool bidib_state_signal_exists(const char *id) { for (size_t i = 0; i < bidib_track_state.signals_dcc->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.signals_dcc, t_bidib_dcc_accessory_state, i).id)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return true; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } static bool bidib_state_peripheral_exists(const char *id) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.peripherals pthread_mutex_lock(&trackstate_peripherals_mutex); for (size_t i = 0; i < bidib_track_state.peripherals->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.peripherals, t_bidib_peripheral_state, i).id)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); return true; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); return false; } static bool bidib_state_segment_exists(const char *id) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.segments pthread_mutex_lock(&trackstate_segments_mutex); for (size_t i = 0; i < bidib_track_state.segments->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.segments, t_bidib_segment_state_intern, i).id->str)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); return true; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); return false; } static bool bidib_state_reverser_exists(const char *id) { - //pthread_rwlock_rdlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.reversers pthread_mutex_lock(&trackstate_reversers_mutex); for (size_t i = 0; i < bidib_track_state.reversers->len; i++) { if (!strcmp(id, g_array_index(bidib_track_state.reversers, t_bidib_reverser_state, i).id)) { - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); return true; } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); return false; } void bidib_state_add_booster(t_bidib_booster_state booster_state) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.boosters + // For accessing bidib_track_state.boosters (devnote: write) pthread_mutex_lock(&trackstate_boosters_mutex); g_array_append_val(bidib_track_state.boosters, booster_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_boosters_mutex); } void bidib_state_add_track_output(t_bidib_track_output_state track_output_state) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.track_outputs + // For accessing bidib_track_state.track_outputs (devnote: write) pthread_mutex_lock(&trackstate_track_outputs_mutex); g_array_append_val(bidib_track_state.track_outputs, track_output_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_track_outputs_mutex); } void bidib_state_add_train_state(t_bidib_train_state_intern train_state) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref and for accessing bidib_track_state.trains + // For bidib_state_get_train_state_ref and for accessing bidib_track_state.trains (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); if (bidib_state_get_train_state_ref(train_state.id->str) == NULL) { g_array_append_val(bidib_track_state.trains, train_state); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); } @@ -609,12 +586,9 @@ bool bidib_state_add_board_point_state(t_bidib_board_accessory_state point_state if (bidib_state_point_exists(point_state.id)) { return true; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.points_board + // For accessing bidib_track_state.points_board (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); - g_array_append_val(bidib_track_state.points_board, point_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -623,12 +597,9 @@ bool bidib_state_add_board_signal_state(t_bidib_board_accessory_state signal_sta if (bidib_state_signal_exists(signal_state.id)) { return true; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.signals_board + // For accessing bidib_track_state.signals_board (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); - g_array_append_val(bidib_track_state.signals_board, signal_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -642,12 +613,9 @@ bool bidib_state_add_dcc_point_state(t_bidib_dcc_accessory_state point_state, } pthread_rwlock_unlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.points_dcc + // For accessing bidib_track_state.points_dcc (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); - g_array_append_val(bidib_track_state.points_dcc, point_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -661,12 +629,9 @@ bool bidib_state_add_dcc_signal_state(t_bidib_dcc_accessory_state signal_state, } pthread_rwlock_unlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.signals_dcc + // For accessing bidib_track_state.signals_dcc (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); - g_array_append_val(bidib_track_state.signals_dcc, signal_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return false; } @@ -675,12 +640,9 @@ bool bidib_state_add_peripheral_state(t_bidib_peripheral_state peripheral_state) if (bidib_state_peripheral_exists(peripheral_state.id)) { return true; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.peripherals + // For accessing bidib_track_state.peripherals (devnote: write) pthread_mutex_lock(&trackstate_peripherals_mutex); - g_array_append_val(bidib_track_state.peripherals, peripheral_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); return false; } @@ -689,12 +651,9 @@ bool bidib_state_add_segment_state(t_bidib_segment_state_intern segment_state) { if (bidib_state_segment_exists(segment_state.id->str)) { return true; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.segments + // For accessing bidib_track_state.segments (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); - g_array_append_val(bidib_track_state.segments, segment_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); return false; } @@ -703,12 +662,9 @@ bool bidib_state_add_reverser_state(t_bidib_reverser_state reverser_state) { if (bidib_state_reverser_exists(reverser_state.id)) { return true; } - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For accessing bidib_track_state.reversers + // For accessing bidib_track_state.reversers (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); - g_array_append_val(bidib_track_state.reversers, reverser_state); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); return false; } @@ -762,8 +718,8 @@ void bidib_state_update_train_available(void) { } void bidib_state_reset(void) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); // For accessing bidib_track_state.points_board, .points_dcc, .signals_board, .signals_dcc + // (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); t_bidib_board_accessory_state *board_accessory_state; for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { @@ -805,7 +761,7 @@ void bidib_state_reset(void) { } pthread_mutex_unlock(&trackstate_accessories_mutex); - // For accessing bidib_track_state.peripherals + // For accessing bidib_track_state.peripherals (devnote: write) pthread_mutex_lock(&trackstate_peripherals_mutex); t_bidib_peripheral_state *peripheral_state; for (size_t i = 0; i < bidib_track_state.peripherals->len; i++) { @@ -818,7 +774,7 @@ void bidib_state_reset(void) { } pthread_mutex_unlock(&trackstate_peripherals_mutex); - // For accessing bidib_track_state.segments + // For accessing bidib_track_state.segments (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); t_bidib_segment_state_intern *segment_state; for (size_t i = 0; i < bidib_track_state.segments->len; i++) { @@ -838,7 +794,7 @@ void bidib_state_reset(void) { } pthread_mutex_unlock(&trackstate_segments_mutex); - // For accessing bidib_track_state.reversers + // For accessing bidib_track_state.reversers (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); t_bidib_reverser_state *reverser_state; for (size_t i = 0; i < bidib_track_state.reversers->len; i++) { @@ -849,7 +805,7 @@ void bidib_state_reset(void) { } pthread_mutex_unlock(&trackstate_reversers_mutex); - // For accessing bidib_track_state.trains + // For accessing bidib_track_state.trains (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state; for (size_t i = 0; i < bidib_track_state.trains->len; i++) { @@ -872,7 +828,7 @@ void bidib_state_reset(void) { } pthread_mutex_unlock(&trackstate_trains_mutex); - // For accessing bidib_track_state.boosters + // For accessing bidib_track_state.boosters (devnote: write) pthread_mutex_lock(&trackstate_boosters_mutex); t_bidib_booster_state *booster_state; for (size_t i = 0; i < bidib_track_state.boosters->len; i++) { @@ -887,7 +843,7 @@ void bidib_state_reset(void) { } pthread_mutex_unlock(&trackstate_boosters_mutex); - // For accessing bidib_track_state.track_outputs + // For accessing bidib_track_state.track_outputs (devnote: write) pthread_mutex_lock(&trackstate_track_outputs_mutex); t_bidib_track_output_state *track_output_state; for (size_t i = 0; i < bidib_track_state.track_outputs->len; i++) { @@ -895,7 +851,6 @@ void bidib_state_reset(void) { t_bidib_track_output_state, i); track_output_state->cs_state = BIDIB_CS_OFF; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_track_outputs_mutex); } diff --git a/src/state/bidib_state_intern.h b/src/state/bidib_state_intern.h index 001f113..b17aded 100644 --- a/src/state/bidib_state_intern.h +++ b/src/state/bidib_state_intern.h @@ -168,7 +168,6 @@ typedef struct { } t_bidib_state_initial_values; extern pthread_rwlock_t bidib_state_trains_rwlock; -//extern pthread_rwlock_t bidib_state_track_rwlock; extern pthread_rwlock_t bidib_state_boards_rwlock; extern pthread_mutex_t trackstate_accessories_mutex; diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 255ab38..b8e36e5 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -38,8 +38,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, const uint8_t *const value_list, unsigned int action_id) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_reverser_state_ref + // For bidib_state_get_reverser_state_ref (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); // For bidib_state_get_reverser_mapping_ref_by_cv pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -88,13 +87,11 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, free(value); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); } void bidib_state_boost_state(t_bidib_node_address node_address, uint8_t power_state) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_booster_state_ref_by_nodeaddr + // For bidib_state_get_booster_state_ref_by_nodeaddr (devnote: write) pthread_mutex_lock(&trackstate_boosters_mutex); t_bidib_booster_state *booster_state = @@ -108,15 +105,13 @@ void bidib_state_boost_state(t_bidib_node_address node_address, uint8_t power_st "No booster configured with node address 0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_boosters_mutex); } void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t number, uint8_t aspect, uint8_t total, uint8_t execution, uint8_t wait, unsigned int action_id) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_board_accessory_state_ref + // For bidib_state_get_board_accessory_state_ref (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); // For bidib_state_get_board_accessory_mapping_ref_by_number pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -173,7 +168,6 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb number, node_address.top, node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); } @@ -247,8 +241,7 @@ void bidib_state_node_lost(t_bidib_unique_id_mod unique_id) { void bidib_state_cs_state(t_bidib_node_address node_address, uint8_t state, unsigned int action_id) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_track_output_state_ref_by_nodeaddr + // For bidib_state_get_track_output_state_ref_by_nodeaddr (devnote: write) pthread_mutex_lock(&trackstate_track_outputs_mutex); t_bidib_track_output_state *track_output_state = @@ -264,7 +257,6 @@ void bidib_state_cs_state(t_bidib_node_address node_address, uint8_t state, "No track output configured for node address 0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_track_outputs_mutex); } @@ -272,8 +264,7 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, unsi // For bidib_state_get_train_state_ref_by_dccaddr and bidib_state_dcc_addr_in_use pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref_by_dccaddr + // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = @@ -291,7 +282,6 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, unsi dcc_address.addrh, dcc_address.addrl); } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } @@ -312,8 +302,7 @@ void bidib_state_cs_accessory_ack(t_bidib_node_address node_address, } void bidib_state_cs_drive(t_bidib_cs_drive_mod params) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref_by_dccaddr + // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = @@ -398,7 +387,6 @@ void bidib_state_cs_drive(t_bidib_cs_drive_mod params) { params.dcc_address.addrh, params.dcc_address.addrl); } } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); } @@ -463,9 +451,7 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p uint8_t portstat, unsigned int action_id) { t_bidib_peripheral_state *peripheral_state; - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - - // For bidib_state_get_peripheral_state_ref + // For bidib_state_get_peripheral_state_ref (devnote: write) pthread_mutex_lock(&trackstate_peripherals_mutex); // For bidib_state_get_peripheral_mapping_ref_by_port pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -504,7 +490,6 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); } @@ -512,9 +497,7 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p uint8_t time) { t_bidib_peripheral_state *peripheral_state; - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - - // For bidib_state_get_peripheral_state_ref + // For bidib_state_get_peripheral_state_ref (devnote: write) pthread_mutex_lock(&trackstate_peripherals_mutex); // For bidib_state_get_peripheral_mapping_ref_by_port pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -537,7 +520,6 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); } @@ -585,8 +567,8 @@ void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool // For bidib_state_log_train_detect and bidib_state_update_train_available pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + // (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); // For bidib_state_log_train_detect and bidib_state_update_train_available pthread_mutex_lock(&trackstate_trains_mutex); @@ -612,7 +594,6 @@ void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool "0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); @@ -624,8 +605,8 @@ void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, // For bidib_state_log_train_detect and bidib_state_update_train_available pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + // (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); // For bidib_state_log_train_detect and bidib_state_update_train_available pthread_mutex_lock(&trackstate_trains_mutex); @@ -657,7 +638,6 @@ void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, } } bidib_state_update_train_available(); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); @@ -665,8 +645,7 @@ void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_void, uint8_t freeze, uint8_t nosignal, unsigned int action_id) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_segment_state_ref + // For bidib_state_get_segment_state_ref (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); // For bidib_state_get_board_ref_by_nodeaddr pthread_rwlock_rdlock(&bidib_state_boards_rwlock); @@ -710,7 +689,6 @@ void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_v node_address.top, node_address.sub, node_address.subsub); } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); } @@ -786,8 +764,8 @@ void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, // For bidib_state_update_train_available and bidib_state_bm_address_log_changes pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available + // (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); // For bidib_state_update_train_available and bidib_state_bm_address_log_changes pthread_mutex_lock(&trackstate_trains_mutex); @@ -827,7 +805,6 @@ void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, "0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); @@ -835,8 +812,7 @@ void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, void bidib_state_bm_current(t_bidib_node_address node_address, uint8_t number, uint8_t current) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_segment_state_ref_by_nodeaddr + // For bidib_state_get_segment_state_ref_by_nodeaddr (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); t_bidib_segment_state_intern *segment_state = bidib_state_get_segment_state_ref_by_nodeaddr(node_address, number); @@ -879,7 +855,6 @@ void bidib_state_bm_current(t_bidib_node_address node_address, uint8_t number, "0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); } @@ -887,8 +862,7 @@ void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, uint8 // For bidib_state_get_train_state_ref_by_dccaddr pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref_by_dccaddr + // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = @@ -900,7 +874,6 @@ void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, uint8 "No train configured for dcc address 0x%02x 0x%02x", dcc_address.addrl, dcc_address.addrh); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } @@ -910,8 +883,7 @@ void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, // For bidib_state_get_train_state_ref_by_dccaddr pthread_rwlock_rdlock(&bidib_state_trains_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref_by_dccaddr + // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = @@ -962,19 +934,18 @@ void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, "No train configured for dcc address 0x%02x 0x%02x", dcc_address.addrl, dcc_address.addrh); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_rwlock_unlock(&bidib_state_trains_rwlock); } void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t length, const uint8_t *const diag_list, unsigned int action_id) { - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_booster_state_ref_by_nodeaddr struct timespec start, middle, end; clock_gettime(CLOCK_MONOTONIC_RAW, &start); + // For bidib_state_get_booster_state_ref_by_nodeaddr (devnote: write) pthread_mutex_lock(&trackstate_boosters_mutex); + clock_gettime(CLOCK_MONOTONIC_RAW, &middle); t_bidib_booster_state *booster_state = bidib_state_get_booster_state_ref_by_nodeaddr(node_address); @@ -1048,7 +1019,6 @@ void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t len "0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_boosters_mutex); clock_gettime(CLOCK_MONOTONIC_RAW, &end); diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index cde4e89..9158086 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -377,14 +377,12 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, message, action_id); dcc_address.addrl = message[data_index]; dcc_address.addrh = message[data_index + 1]; - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // Both for bidib_state_cs_accessory_ack + // Both for bidib_state_cs_accessory_ack (devnote: write for first) pthread_mutex_lock(&trackstate_accessories_mutex); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); bidib_state_cs_accessory_ack(node_address, dcc_address, message[data_index + 2]); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); free(message); break; @@ -413,20 +411,18 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, message, action_id); dcc_address.addrl = message[data_index]; dcc_address.addrh = message[data_index + 1]; - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // Both for bidib_state_cs_accessory_manual + // Both for bidib_state_cs_accessory_manual (devnote: write for first) pthread_mutex_lock(&trackstate_accessories_mutex); pthread_rwlock_rdlock(&bidib_state_boards_rwlock); bidib_state_cs_accessory_manual(node_address, dcc_address, message[data_index + 2]); pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); free(message); break; case MSG_LC_STAT: // update state - //bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, - // message, action_id); + bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, + message, action_id); peripheral_port.port0 = message[data_index]; peripheral_port.port1 = message[data_index + 1]; bidib_state_lc_stat(node_address, peripheral_port, message[data_index + 2], action_id); diff --git a/test/unit/bidib_highlevel_message_tests.c b/test/unit/bidib_highlevel_message_tests.c index 8f7fd3e..3b8c9cd 100644 --- a/test/unit/bidib_highlevel_message_tests.c +++ b/test/unit/bidib_highlevel_message_tests.c @@ -85,6 +85,7 @@ static void board_receives_response(const uint8_t response_type) { } static void set_all_boards_and_trains_connected(void) { + // For accessing bidib_boards pthread_rwlock_wrlock(&bidib_state_boards_rwlock); t_bidib_board *board_i; for (size_t i = 0; i < bidib_boards->len; i++) { @@ -94,14 +95,12 @@ static void set_all_boards_and_trains_connected(void) { } } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref + // For bidib_state_get_train_state_ref (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref("train1"); if (train_state != NULL) { train_state->on_track = true; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); } diff --git a/test/unit/bidib_parallel_tests.c b/test/unit/bidib_parallel_tests.c index 4eabc08..e682da9 100644 --- a/test/unit/bidib_parallel_tests.c +++ b/test/unit/bidib_parallel_tests.c @@ -77,8 +77,7 @@ static void set_all_boards_and_trains_connected(void) { } pthread_rwlock_unlock(&bidib_state_boards_rwlock); - //pthread_rwlock_wrlock(&bidib_state_track_rwlock); - // For bidib_state_get_train_state_ref + // For bidib_state_get_train_state_ref (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref("train1"); @@ -89,7 +88,6 @@ static void set_all_boards_and_trains_connected(void) { if (train_state != NULL) { train_state->on_track = true; } - //pthread_rwlock_unlock(&bidib_state_track_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); } From 054dd38508da62fb4916dc9869eb1bba49a4b720 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 11:47:09 +0100 Subject: [PATCH 37/51] improved flush-batch to not require byte-per-byte fallback --- src/transmission/bidib_transmission_send.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index 77130f0..c24c2f8 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -132,9 +132,11 @@ static void bidib_flush_impl(void) { for (size_t i = 0; i < buffer_index; ++i) { // At most 2 more chars can be added in one loop iteration if (aux_index + 3 >= PACKET_BUFFER_AUX_SIZE) { - // Too big for flush_batch. Fallback to traditional one-by-one send. - bidib_flush_impl_old(); - return; + // aux_buffer full. Send its current contents and continue. + write_bytes((uint8_t*)buffer_aux, aux_index); + // reset the aux_index but NOT the buffer_index, + // as we want to continue sending the rest of the buffer + aux_index = 0; } crc = bidib_crc_array[buffer[i] ^ crc]; if (buffer[i] == BIDIB_PKT_MAGIC || buffer[i] == BIDIB_PKT_ESCAPE) { @@ -147,10 +149,11 @@ static void bidib_flush_impl(void) { // At most 3 more chars can be added in the code below if (aux_index + 4 >= PACKET_BUFFER_AUX_SIZE) { - // Too big for flush batch, can't fit crc+delim in aux buffer. - // Fallback to traditional one-by-one send. - bidib_flush_impl_old(); - return; + // aux_buffer full. Send its current contents and continue. + write_bytes((uint8_t*)buffer_aux, aux_index); + // reset the aux_index but NOT the buffer_index, + // as we want to continue sending the rest of the buffer + aux_index = 0; } // send crc byte (+ escape if necessary) @@ -162,7 +165,7 @@ static void bidib_flush_impl(void) { } buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv - // Batch-write aux buffer. + // Batch-write aux buffer and reset the buffer index. write_bytes((uint8_t*)buffer_aux, aux_index); buffer_index = 0; From b9f67c0d2496788e06630be06e62fd93e5e8026a Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 12:17:28 +0100 Subject: [PATCH 38/51] remove commented code with the dupl loop for train peripheral bits --- src/highlevel/bidib_highlevel_setter.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index 472896b..da85b2b 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -569,17 +569,9 @@ static void bidib_get_current_train_peripheral_bits(const t_bidib_train *const t const t_bidib_train_peripheral_mapping *const mapping_i = &g_array_index(train->peripherals, t_bidib_train_peripheral_mapping, i); if (mapping_i->bit >= start && mapping_i->bit <= end) { - ///NOTE: j is actually not used in the nested loop, is that intentional? - ///TODO: Test. const t_bidib_train_peripheral_state *const train_per_state_i = bidib_state_get_train_peripheral_state_by_bit(train_state, mapping_i->bit); *bits |= (train_per_state_i->state << (mapping_i->bit % 8)); - /* - for (size_t j = 0; j < train->peripherals->len; j++) { - const t_bidib_train_peripheral_state *const train_per_state_i = - bidib_state_get_train_peripheral_state_by_bit(train_state, mapping_i->bit); - *bits |= (train_per_state_i->state << (mapping_i->bit % 8)); - }*/ } } } From 6dcd97fa2e43a207f804ca0d02cf4a0cc3337cd6 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 12:19:09 +0100 Subject: [PATCH 39/51] Fixed alloc and free for reverser_state->data state_id. --- src/state/bidib_state.c | 6 ++++++ src/state/bidib_state_free.c | 3 +++ src/state/bidib_state_setter.c | 37 +++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 23d1e7f..946f10b 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -718,6 +718,12 @@ void bidib_state_update_train_available(void) { } void bidib_state_reset(void) { + /// NOTE: Currently, this function is only called during startup/setup. + // Therefore, all pointers that are simply being set to NULL here + // were not malloc'd to something before, or they were freed before + // (on the previous bidib_stop). If this changes, i.e. if this function + // gets called before bidib_state_free, and with actual state contained, + // this'll cause a memory leak. // For accessing bidib_track_state.points_board, .points_dcc, .signals_board, .signals_dcc // (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); diff --git a/src/state/bidib_state_free.c b/src/state/bidib_state_free.c index aa18f7c..fdf9c9b 100644 --- a/src/state/bidib_state_free.c +++ b/src/state/bidib_state_free.c @@ -72,6 +72,9 @@ void bidib_state_free_single_peripheral_state(t_bidib_peripheral_state periphera } void bidib_state_free_single_reverser_state(t_bidib_reverser_state reverser_state) { + if (reverser_state.data.state_id != NULL) { + free(reverser_state.data.state_id); + } if (reverser_state.id != NULL) { free(reverser_state.id); } diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index b8e36e5..ff47595 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -54,12 +54,21 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, if (mapping != NULL) { t_bidib_reverser_state *reverser_state = bidib_state_get_reverser_state_ref(mapping->id->str); - ///NOTE: This is a shallow copy/not a strdup. - ///TODO: Change to deep copy, as otherwise the lock/mutex protection is not accurate - // anymore: mapping is a part of the boards, whilst the reverser state is part of - // the trackstate. - // Will have to adjust all other positions where this is assigned/reset. - reverser_state->data.state_id = mapping->id->str; + if (reverser_state == NULL) { + syslog_libbidib(LOG_ERR, + "Feedback for vendor-specific configuration %s (value %s) " + "with node address 0x%02x 0x%02x 0x%02x 0x00 has been discarded, " + "the reverser state is NULL", + name, value, + node_address.top, node_address.sub, node_address.subsub); + pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); + free(name); + free(value); + return; + } + + reverser_state->data.state_id = strdup(mapping->id->str); switch (value[0]) { case '0': reverser_state->data.state_value = BIDIB_REV_EXEC_STATE_OFF; @@ -82,12 +91,12 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, name, value, node_address.top, node_address.sub, node_address.subsub); } - - free(name); - free(value); - + pthread_rwlock_unlock(&bidib_state_boards_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); + + free(name); + free(value); } void bidib_state_boost_state(t_bidib_node_address node_address, uint8_t power_state) { @@ -462,6 +471,7 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p (peripheral_state = bidib_state_get_peripheral_state_ref(peripheral_mapping->id->str)) != NULL) { ///TODO: Does this cause a memory leak? maybe not, as it points to memory allocated for // the aspect mapping probably. Is it assigned/malloc'd elsewhere? + ///NOTE: Related to note on shallow copy in bidib_state_vendor I think. peripheral_state->data.state_id = NULL; t_bidib_aspect *aspect_mapping; for (size_t i = 0; i < peripheral_mapping->aspects->len; i++) { @@ -476,10 +486,9 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p "Aspect 0x%02x of peripheral %s is not mapped in config files", portstat, peripheral_mapping->id->str); } else { - // Temporarily disabled for debugging (less logs to read) - //syslog_libbidib(LOG_INFO, - // "Feedback for action id %d: Peripheral: %s has aspect: %s (0x%02x)", - // action_id, peripheral_mapping->id->str, aspect_mapping->id->str, portstat); + syslog_libbidib(LOG_INFO, + "Feedback for action id %d: Peripheral: %s has aspect: %s (0x%02x)", + action_id, peripheral_mapping->id->str, aspect_mapping->id->str, portstat); } peripheral_state->data.state_value = portstat; } else { From 1f08eb81729880a2af8664ca7670844ab8e4c6b6 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 13:24:29 +0100 Subject: [PATCH 40/51] where sensible, set pointer to NULL after free, and also make deep copies for state.data.state_id members of various kinds --- example/src/bidib_system_test.c | 52 ++++--- src/highlevel/bidib_highlevel_getter.c | 33 +++-- src/highlevel/bidib_highlevel_setter.c | 4 +- src/state/bidib_state.c | 4 + src/state/bidib_state_free.c | 128 ++++++++++++++---- src/state/bidib_state_setter.c | 21 ++- .../bidib_transmission_node_states.c | 4 + src/transmission/bidib_transmission_receive.c | 3 + test/physical/swtbahn-standard/main.c | 1 + 9 files changed, 182 insertions(+), 68 deletions(-) diff --git a/example/src/bidib_system_test.c b/example/src/bidib_system_test.c index 1d95b78..8af278d 100755 --- a/example/src/bidib_system_test.c +++ b/example/src/bidib_system_test.c @@ -34,36 +34,30 @@ void print_board_accessory_state_query(t_bidib_unified_accessory_state_query que } void print_points(void) { - GString *points = g_string_new(""); - t_bidib_id_list_query query = bidib_get_connected_points(); - for (size_t i = 0; i < query.length; i++) { - t_bidib_unified_accessory_state_query point_state = - bidib_get_point_state(query.ids[i]); - - GString *execution_state = g_string_new(""); - if (point_state.type == BIDIB_ACCESSORY_BOARD) { - g_string_printf(execution_state, "(target state%s reached)", - point_state.board_accessory_state.execution_state ? - " not" : ""); - } - char execution_state_str[execution_state->len + 1]; - strcpy(execution_state_str, execution_state->str); - g_string_free(execution_state, true); - - g_string_append_printf(points, "%s%s - state: %s %s", - i != 0 ? "\n" : "", query.ids[i], - point_state.type == BIDIB_ACCESSORY_BOARD ? - point_state.board_accessory_state.state_id : - point_state.dcc_accessory_state.state_id, - execution_state_str); - bidib_free_unified_accessory_state_query(point_state); + GString *points = g_string_new(""); + t_bidib_id_list_query query = bidib_get_connected_points(); + for (size_t i = 0; i < query.length; i++) { + t_bidib_unified_accessory_state_query point_state = bidib_get_point_state(query.ids[i]); + + GString *execution_state = g_string_new(""); + if (point_state.type == BIDIB_ACCESSORY_BOARD) { + g_string_printf(execution_state, "(target state%s reached)", + point_state.board_accessory_state.execution_state ? + " not" : ""); } - bidib_free_id_list_query(query); - char response[points->len + 1]; - strcpy(response, points->str); - g_string_free(points, true); - - printf("%s\n", response); + + g_string_append_printf(points, "%s%s - state: %s %s", + i != 0 ? "\n" : "", query.ids[i], + point_state.type == BIDIB_ACCESSORY_BOARD ? + point_state.board_accessory_state.state_id : + point_state.dcc_accessory_state.state_id, + execution_state->str); + g_string_free(execution_state, true); + bidib_free_unified_accessory_state_query(point_state); + } + bidib_free_id_list_query(query); + printf("%s\n", points->str); + g_string_free(points, true); } void print_segment_state_query(t_bidib_segment_state_query seg_state_query) { diff --git a/src/highlevel/bidib_highlevel_getter.c b/src/highlevel/bidib_highlevel_getter.c index 7377360..5e47108 100644 --- a/src/highlevel/bidib_highlevel_getter.c +++ b/src/highlevel/bidib_highlevel_getter.c @@ -1441,33 +1441,33 @@ t_bidib_id_list_query bidib_get_peripheral_aspects(const char *peripheral) { void bidib_free_track_state(t_bidib_track_state track_state) { for (size_t i = 0; i < track_state.points_board_count; i++) { bidib_state_free_single_board_accessory_state(track_state.points_board[i]); - free(track_state.points_board[i].data.state_id); } free(track_state.points_board); for (size_t i = 0; i < track_state.points_dcc_count; i++) { bidib_state_free_single_dcc_accessory_state(track_state.points_dcc[i]); - free(track_state.points_dcc[i].data.state_id); } free(track_state.points_dcc); for (size_t i = 0; i < track_state.signals_board_count; i++) { bidib_state_free_single_board_accessory_state(track_state.signals_board[i]); - free(track_state.signals_board[i].data.state_id); } free(track_state.signals_board); for (size_t i = 0; i < track_state.signals_dcc_count; i++) { bidib_state_free_single_dcc_accessory_state(track_state.signals_dcc[i]); - free(track_state.signals_dcc[i].data.state_id); } free(track_state.signals_dcc); for (size_t i = 0; i < track_state.peripherals_count; i++) { bidib_state_free_single_peripheral_state(track_state.peripherals[i]); - free(track_state.peripherals[i].data.state_id); } free(track_state.peripherals); + + for (size_t i = 0; i < track_state.reversers_count; i++) { + bidib_state_free_single_reverser_state(track_state.reversers[i]); + } + free(track_state.reversers); for (size_t i = 0; i < track_state.segments_count; i++) { bidib_state_free_single_segment_state(track_state.segments[i]); @@ -1494,10 +1494,12 @@ void bidib_free_unified_accessory_state_query(t_bidib_unified_accessory_state_qu if (query.type == BIDIB_ACCESSORY_BOARD) { if (query.board_accessory_state.state_id != NULL) { free(query.board_accessory_state.state_id); + query.board_accessory_state.state_id = NULL; } } else { if (query.dcc_accessory_state.state_id != NULL) { free(query.dcc_accessory_state.state_id); + query.dcc_accessory_state.state_id = NULL; } } } @@ -1505,62 +1507,77 @@ void bidib_free_unified_accessory_state_query(t_bidib_unified_accessory_state_qu void bidib_free_peripheral_state_query(t_bidib_peripheral_state_query query) { if (query.data.state_id != NULL) { free(query.data.state_id); + query.data.state_id = NULL; } } void bidib_free_segment_state_query(t_bidib_segment_state_query query) { if (query.data.dcc_addresses != NULL) { free(query.data.dcc_addresses); + query.data.dcc_addresses = NULL; } } void bidib_free_reverser_state_query(t_bidib_reverser_state_query query) { if (query.data.state_id != NULL) { free(query.data.state_id); + query.data.state_id = NULL; } } void bidib_free_id_list_query(t_bidib_id_list_query query) { if (query.ids != NULL) { for (size_t i = 0; i < query.length; i++) { - free(query.ids[i]); + if (query.ids[i] != NULL) { + free(query.ids[i]); + } } free(query.ids); + query.ids = NULL; } } void bidib_free_board_features_query(t_bidib_board_features_query query) { if (query.features != NULL) { free(query.features); + query.features = NULL; } } void bidib_free_id_query(t_bidib_id_query query) { if (query.id != NULL) { free(query.id); + query.id = NULL; } } void bidib_free_unique_id_list_query(t_bidib_unique_id_list_query query) { if (query.unique_ids != NULL) { free(query.unique_ids); + query.unique_ids = NULL; } } void bidib_free_train_state_query(t_bidib_train_state_query query) { if (query.data.peripherals != NULL) { for (size_t i = 0; i < query.data.peripheral_cnt; i++) { - free(query.data.peripherals[i].id); + if (query.data.peripherals[i].id != NULL) { + free(query.data.peripherals[i].id); + } } free(query.data.peripherals); + query.data.peripherals = NULL; } } void bidib_free_train_position_query(t_bidib_train_position_query query) { if (query.segments != NULL) { for (size_t i = 0; i < query.length; i++) { - free(query.segments[i]); + if (query.segments[i] != NULL) { + free(query.segments[i]); + } } free(query.segments); + query.segments = NULL; } } diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index da85b2b..81c6cb3 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -154,7 +154,7 @@ int bidib_switch_point(const char *point, const char *aspect) { bidib_state_get_dcc_accessory_state_ref(point, true); int ret = 0; if (accessory_state != NULL) { - accessory_state->data.state_id = aspect_mapping->id->str; + accessory_state->data.state_id = strdup(aspect_mapping->id->str); syslog_libbidib(LOG_NOTICE, "Switch point: %s on board: %s (0x%02x 0x%02x " "0x%02x 0x00) to aspect: %s with action id: %d", point, board_i->id->str, tmp_addr.top, tmp_addr.sub, @@ -268,7 +268,7 @@ int bidib_set_signal(const char *signal, const char *aspect) { t_bidib_dcc_accessory_state *accessory_state = bidib_state_get_dcc_accessory_state_ref(signal, false); if (accessory_state != NULL) { - accessory_state->data.state_id = aspect_mapping->id->str; + accessory_state->data.state_id = strdup(aspect_mapping->id->str); syslog_libbidib(LOG_NOTICE, "Set signal: %s on board: %s (0x%02x 0x%02x " "0x%02x 0x00) to aspect: %s with action id: %d", signal, board_i->id->str, tmp_addr.top, tmp_addr.sub, diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 946f10b..463826d 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -211,6 +211,7 @@ void bidib_state_init_allocation_table(void) { sub_interface = g_queue_pop_head(sub_iface_queue); reset = bidib_state_query_nodetab(*sub_interface, sub_iface_queue); free(sub_interface); + sub_interface = NULL; } if (!reset) { // Node table processed successfully. @@ -221,6 +222,7 @@ void bidib_state_init_allocation_table(void) { while (!g_queue_is_empty(sub_iface_queue)) { sub_interface = g_queue_pop_head(sub_iface_queue); free(sub_interface); + sub_interface = NULL; } } g_queue_free(sub_iface_queue); @@ -285,9 +287,11 @@ void bidib_state_set_board_features(void) { } } free(message); + message = NULL; break; } else { free(message); + message = NULL; } } } diff --git a/src/state/bidib_state_free.c b/src/state/bidib_state_free.c index fdf9c9b..c5fc74b 100644 --- a/src/state/bidib_state_free.c +++ b/src/state/bidib_state_free.c @@ -38,72 +38,99 @@ void bidib_state_free_single_initial_value(t_bidib_state_initial_value value) { if (value.id != NULL) { g_string_free(value.id, TRUE); + value.id = NULL; } if (value.value != NULL) { g_string_free(value.value, TRUE); + value.value = NULL; } } void bidib_state_free_single_train_initial_value(t_bidib_state_train_initial_value value) { if (value.id != NULL) { g_string_free(value.id, TRUE); + value.id = NULL; } if (value.train != NULL) { g_string_free(value.train, TRUE); + value.train = NULL; } } void bidib_state_free_single_board_accessory_state(t_bidib_board_accessory_state accessory_state) { if (accessory_state.id != NULL) { free(accessory_state.id); + accessory_state.id = NULL; + } + if (accessory_state.data.state_id != NULL) { + free(accessory_state.data.state_id); + accessory_state.data.state_id = NULL; } } void bidib_state_free_single_dcc_accessory_state(t_bidib_dcc_accessory_state accessory_state) { if (accessory_state.id != NULL) { free(accessory_state.id); + accessory_state.id = NULL; + } + if (accessory_state.data.state_id != NULL) { + free(accessory_state.data.state_id); + accessory_state.data.state_id = NULL; } } void bidib_state_free_single_peripheral_state(t_bidib_peripheral_state peripheral_state) { if (peripheral_state.id != NULL) { free(peripheral_state.id); + peripheral_state.id = NULL; + } + if (peripheral_state.data.state_id != NULL) { + free(peripheral_state.data.state_id); + peripheral_state.data.state_id = NULL; } } void bidib_state_free_single_reverser_state(t_bidib_reverser_state reverser_state) { - if (reverser_state.data.state_id != NULL) { - free(reverser_state.data.state_id); - } if (reverser_state.id != NULL) { free(reverser_state.id); + reverser_state.id = NULL; + } + if (reverser_state.data.state_id != NULL) { + free(reverser_state.data.state_id); + reverser_state.data.state_id = NULL; } } void bidib_state_free_single_segment_state(t_bidib_segment_state segment_state) { if (segment_state.id != NULL) { free(segment_state.id); + segment_state.id = NULL; } if (segment_state.data.dcc_addresses != NULL) { free(segment_state.data.dcc_addresses); + segment_state.data.dcc_addresses = NULL; } } void bidib_state_free_single_segment_state_intern(t_bidib_segment_state_intern segment_state) { if (segment_state.id != NULL) { g_string_free(segment_state.id, TRUE); + segment_state.id = NULL; } if (segment_state.length != NULL) { g_string_free(segment_state.length, TRUE); + segment_state.length = NULL; } if (segment_state.dcc_addresses != NULL) { g_array_free(segment_state.dcc_addresses, TRUE); + segment_state.dcc_addresses = NULL; } } void bidib_state_free_single_train_state(t_bidib_train_state train_state) { if (train_state.id != NULL) { free(train_state.id); + train_state.id = NULL; } if (train_state.data.peripherals != NULL) { for (size_t i = 0; i < train_state.data.peripheral_cnt; i++) { @@ -112,12 +139,14 @@ void bidib_state_free_single_train_state(t_bidib_train_state train_state) { } } free(train_state.data.peripherals); + train_state.data.peripherals = NULL; } } void bidib_state_free_single_train_state_intern(t_bidib_train_state_intern train_state) { if (train_state.id != NULL) { g_string_free(train_state.id, TRUE); + train_state.id = NULL; } if (train_state.peripherals != NULL) { t_bidib_train_peripheral_state state_i; @@ -129,25 +158,35 @@ void bidib_state_free_single_train_state_intern(t_bidib_train_state_intern train } } g_array_free(train_state.peripherals, TRUE); + train_state.peripherals = NULL; } } void bidib_state_free_single_booster_state(t_bidib_booster_state booster_state) { if (booster_state.id != NULL) { free(booster_state.id); + booster_state.id = NULL; } } void bidib_state_free_single_track_output_state(t_bidib_track_output_state to_state) { if (to_state.id != NULL) { free(to_state.id); + to_state.id = NULL; } } void bidib_state_free_single_board(t_bidib_board board) { - g_string_free(board.id, TRUE); - - g_array_free(board.features, TRUE); + if (board.id != NULL) { + g_string_free(board.id, TRUE); + board.id = NULL; + } + + if (board.features != NULL) { + g_array_free(board.features, TRUE); + board.features = NULL; + } + t_bidib_board_accessory_mapping tmp_board_acc_mapping; t_bidib_dcc_accessory_mapping tmp_dcc_acc_mapping; @@ -158,96 +197,137 @@ void bidib_state_free_single_board(t_bidib_board board) { for (size_t i = 0; i < board.points_board->len; i++) { tmp_board_acc_mapping = g_array_index(board.points_board, t_bidib_board_accessory_mapping, i); - g_string_free(tmp_board_acc_mapping.id, TRUE); + if (tmp_board_acc_mapping.id != NULL) { + g_string_free(tmp_board_acc_mapping.id, TRUE); + } for (size_t j = 0; j < tmp_board_acc_mapping.aspects->len; j++) { tmp_aspect = g_array_index(tmp_board_acc_mapping.aspects, t_bidib_aspect, j); - g_string_free(tmp_aspect.id, TRUE); + if (tmp_aspect.id != NULL) { + g_string_free(tmp_aspect.id, TRUE); + } } g_array_free(tmp_board_acc_mapping.aspects, TRUE); } g_array_free(board.points_board, TRUE); + board.points_board = NULL; for (size_t i = 0; i < board.points_dcc->len; i++) { tmp_dcc_acc_mapping = g_array_index(board.points_dcc, t_bidib_dcc_accessory_mapping, i); - g_string_free(tmp_dcc_acc_mapping.id, TRUE); + if (tmp_dcc_acc_mapping.id != NULL) { + g_string_free(tmp_dcc_acc_mapping.id, TRUE); + } for (size_t j = 0; j < tmp_dcc_acc_mapping.aspects->len; j++) { tmp_dcc_aspect = g_array_index(tmp_dcc_acc_mapping.aspects, t_bidib_dcc_aspect, j); - g_string_free(tmp_dcc_aspect.id, TRUE); - g_array_free(tmp_dcc_aspect.port_values, TRUE); + if (tmp_dcc_aspect.id != NULL) { + g_string_free(tmp_dcc_aspect.id, TRUE); + } + if (tmp_dcc_aspect.port_values != NULL) { + g_array_free(tmp_dcc_aspect.port_values, TRUE); + } } g_array_free(tmp_dcc_acc_mapping.aspects, TRUE); } g_array_free(board.points_dcc, TRUE); + board.points_dcc = NULL; for (size_t i = 0; i < board.signals_board->len; i++) { tmp_board_acc_mapping = g_array_index(board.signals_board, t_bidib_board_accessory_mapping, i); - g_string_free(tmp_board_acc_mapping.id, TRUE); + if (tmp_board_acc_mapping.id != NULL) { + g_string_free(tmp_board_acc_mapping.id, TRUE); + } for (size_t j = 0; j < tmp_board_acc_mapping.aspects->len; j++) { tmp_aspect = g_array_index(tmp_board_acc_mapping.aspects, t_bidib_aspect, j); - g_string_free(tmp_aspect.id, TRUE); + if (tmp_aspect.id != NULL) { + g_string_free(tmp_aspect.id, TRUE); + } } g_array_free(tmp_board_acc_mapping.aspects, TRUE); } g_array_free(board.signals_board, TRUE); + board.signals_board = NULL; for (size_t i = 0; i < board.signals_dcc->len; i++) { tmp_dcc_acc_mapping = g_array_index(board.signals_dcc, t_bidib_dcc_accessory_mapping, i); - g_string_free(tmp_dcc_acc_mapping.id, TRUE); + if (tmp_dcc_acc_mapping.id != NULL) { + g_string_free(tmp_dcc_acc_mapping.id, TRUE); + } for (size_t j = 0; j < tmp_dcc_acc_mapping.aspects->len; j++) { tmp_dcc_aspect = g_array_index(tmp_dcc_acc_mapping.aspects, t_bidib_dcc_aspect, j); - g_string_free(tmp_dcc_aspect.id, TRUE); - g_array_free(tmp_dcc_aspect.port_values, TRUE); + if (tmp_dcc_aspect.id != NULL) { + g_string_free(tmp_dcc_aspect.id, TRUE); + } + if (tmp_dcc_aspect.port_values != NULL) { + g_array_free(tmp_dcc_aspect.port_values, TRUE); + } } g_array_free(tmp_dcc_acc_mapping.aspects, TRUE); } g_array_free(board.signals_dcc, TRUE); + board.signals_dcc = NULL; for (size_t i = 0; i < board.peripherals->len; i++) { tmp_peripheral_mapping = g_array_index(board.peripherals, t_bidib_peripheral_mapping, i); - g_string_free(tmp_peripheral_mapping.id, TRUE); + if (tmp_peripheral_mapping.id != NULL) { + g_string_free(tmp_peripheral_mapping.id, TRUE); + } for (size_t j = 0; j < tmp_peripheral_mapping.aspects->len; j++) { tmp_aspect = g_array_index(tmp_peripheral_mapping.aspects, t_bidib_aspect, j); - g_string_free(tmp_aspect.id, TRUE); + if (tmp_aspect.id != NULL) { + g_string_free(tmp_aspect.id, TRUE); + } } g_array_free(tmp_peripheral_mapping.aspects, TRUE); } g_array_free(board.peripherals, TRUE); + board.peripherals = NULL; for (size_t i = 0; i < board.segments->len; i++) { - g_string_free(g_array_index(board.segments, - t_bidib_segment_mapping, i).id, TRUE); + t_bidib_segment_mapping tmp = g_array_index(board.segments, t_bidib_segment_mapping, i); + if (tmp.id != NULL) { + g_string_free(tmp.id, TRUE); + } } g_array_free(board.segments, TRUE); + board.segments = NULL; for (size_t i = 0; i < board.reversers->len; i++) { - g_string_free(g_array_index(board.reversers, - t_bidib_reverser_mapping, i).id, TRUE); + t_bidib_reverser_mapping tmp = g_array_index(board.reversers, t_bidib_reverser_mapping, i); + if (tmp.id != NULL) { + g_string_free(tmp.id, TRUE); + } } g_array_free(board.reversers, TRUE); + board.reversers = NULL; } void bidib_state_free_single_train(t_bidib_train train) { if (train.id != NULL) { g_string_free(train.id, TRUE); + train.id = NULL; } if (train.calibration != NULL) { g_array_free(train.calibration, TRUE); + train.calibration = NULL; } if (train.peripherals != NULL) { for (size_t i = 0; i < train.peripherals->len; i++) { - g_string_free(g_array_index(train.peripherals, - t_bidib_train_peripheral_mapping, i).id, TRUE); + t_bidib_train_peripheral_mapping tmp = + g_array_index(train.peripherals, t_bidib_train_peripheral_mapping, i); + if (tmp.id != NULL) { + g_string_free(tmp.id, TRUE); + } } g_array_free(train.peripherals, TRUE); + train.peripherals = NULL; } } diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index ff47595..c5a43ef 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -68,6 +68,11 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, return; } + if (reverser_state->data.state_id != NULL) { + free(reverser_state->data.state_id); + reverser_state->data.state_id = NULL; + } + reverser_state->data.state_id = strdup(mapping->id->str); switch (value[0]) { case '0': @@ -130,12 +135,15 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb t_bidib_board_accessory_state *accessory_state; if (accessory_mapping != NULL && (accessory_state = bidib_state_get_board_accessory_state_ref(accessory_mapping->id->str, point)) != NULL) { + if (accessory_state->data.state_id != NULL) { + free(accessory_state->data.state_id); + } accessory_state->data.state_id = NULL; t_bidib_aspect *aspect_mapping; for (size_t i = 0; i < accessory_mapping->aspects->len; i++) { aspect_mapping = &g_array_index(accessory_mapping->aspects, t_bidib_aspect, i); if (aspect_mapping->value == aspect) { - accessory_state->data.state_id = aspect_mapping->id->str; + accessory_state->data.state_id = strdup(aspect_mapping->id->str); break; } } @@ -431,6 +439,9 @@ void bidib_state_cs_accessory(t_bidib_node_address node_address, if (accessory_mapping != NULL && (accessory_state = bidib_state_get_dcc_accessory_state_ref(accessory_mapping->id->str, point)) != NULL) { + if (accessory_state->data.state_id != NULL) { + free(accessory_state->data.state_id); + } accessory_state->data.state_id = NULL; accessory_state->data.state_value = (uint8_t) (params.data & 0x1F); if (params.data & (1 << 5)) { @@ -469,15 +480,15 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); if (peripheral_mapping != NULL && (peripheral_state = bidib_state_get_peripheral_state_ref(peripheral_mapping->id->str)) != NULL) { - ///TODO: Does this cause a memory leak? maybe not, as it points to memory allocated for - // the aspect mapping probably. Is it assigned/malloc'd elsewhere? - ///NOTE: Related to note on shallow copy in bidib_state_vendor I think. + if (peripheral_state->data.state_id != NULL) { + free(peripheral_state->data.state_id); + } peripheral_state->data.state_id = NULL; t_bidib_aspect *aspect_mapping; for (size_t i = 0; i < peripheral_mapping->aspects->len; i++) { aspect_mapping = &g_array_index(peripheral_mapping->aspects, t_bidib_aspect, i); if (aspect_mapping->value == portstat) { - peripheral_state->data.state_id = aspect_mapping->id->str; + peripheral_state->data.state_id = strdup(aspect_mapping->id->str); break; } } diff --git a/src/transmission/bidib_transmission_node_states.c b/src/transmission/bidib_transmission_node_states.c index acd7248..5108abe 100644 --- a/src/transmission/bidib_transmission_node_states.c +++ b/src/transmission/bidib_transmission_node_states.c @@ -192,6 +192,7 @@ unsigned int bidib_node_state_update(const uint8_t *const addr_stack, uint8_t re state->current_max_respond -= bidib_response_info[response->type][1]; action_id = response->action_id; free(response); + response = NULL; bidib_node_try_queued_messages(state); break; } else if (difftime(current_time, response->creation_time) >= @@ -205,6 +206,7 @@ unsigned int bidib_node_state_update(const uint8_t *const addr_stack, uint8_t re g_queue_pop_head(state->response_queue); state->current_max_respond -= bidib_response_info[response->type][1]; free(response); + response = NULL; if (!g_queue_is_empty(state->response_queue)) { response = g_queue_peek_head(state->response_queue); } else { @@ -236,6 +238,7 @@ void bidib_node_update_stall(const uint8_t *const addr_stack, uint8_t stall_stat bidib_node_try_queued_messages(waiting_node_state); } free(elem); + elem = NULL; } } else { state->stall = true; @@ -303,6 +306,7 @@ void bidib_node_state_table_reset(bool lock_node_state_table_access) { } g_queue_free(value->message_queue); free(value); + value = NULL; g_hash_table_iter_remove(&iter); } } diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 9158086..dfec61f 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -108,6 +108,7 @@ void bidib_uplink_queue_free(void) { if (uplink_queue != NULL) { bidib_uplink_queue_reset(false); g_queue_free(uplink_queue); + uplink_queue = NULL; } pthread_mutex_unlock(&bidib_uplink_queue_mutex); syslog_libbidib(LOG_INFO, "Message queue freed"); @@ -133,6 +134,7 @@ void bidib_uplink_error_queue_free(void) { if (uplink_error_queue != NULL) { bidib_uplink_error_queue_reset(false); g_queue_free(uplink_error_queue); + uplink_error_queue = NULL; } pthread_mutex_unlock(&bidib_uplink_error_queue_mutex); syslog_libbidib(LOG_INFO, "Error message queue freed"); @@ -158,6 +160,7 @@ void bidib_uplink_intern_queue_free(void) { if (uplink_intern_queue != NULL) { bidib_uplink_intern_queue_reset(false); g_queue_free(uplink_intern_queue); + uplink_intern_queue = NULL; } pthread_mutex_unlock(&bidib_uplink_intern_queue_mutex); syslog_libbidib(LOG_INFO, "Intern message queue freed"); diff --git a/test/physical/swtbahn-standard/main.c b/test/physical/swtbahn-standard/main.c index f83e6c5..f551f68 100755 --- a/test/physical/swtbahn-standard/main.c +++ b/test/physical/swtbahn-standard/main.c @@ -104,6 +104,7 @@ int main(int argc, char **argv) { } testsuite_stopBidib(); + free(result->points); free(result); return 0; From e56b03fcccef714e5e698f376617cc570c7df164 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 13:27:32 +0100 Subject: [PATCH 41/51] fix missing check if mem has to be freed and remove unnecessary setting to NULL. --- src/highlevel/bidib_highlevel_setter.c | 6 ++++++ src/state/bidib_state_setter.c | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index 81c6cb3..e48bc56 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -154,6 +154,9 @@ int bidib_switch_point(const char *point, const char *aspect) { bidib_state_get_dcc_accessory_state_ref(point, true); int ret = 0; if (accessory_state != NULL) { + if (accessory_state->data.state_id != NULL) { + free(accessory_state->data.state_id); + } accessory_state->data.state_id = strdup(aspect_mapping->id->str); syslog_libbidib(LOG_NOTICE, "Switch point: %s on board: %s (0x%02x 0x%02x " "0x%02x 0x00) to aspect: %s with action id: %d", @@ -268,6 +271,9 @@ int bidib_set_signal(const char *signal, const char *aspect) { t_bidib_dcc_accessory_state *accessory_state = bidib_state_get_dcc_accessory_state_ref(signal, false); if (accessory_state != NULL) { + if (accessory_state->data.state_id != NULL) { + free(accessory_state->data.state_id); + } accessory_state->data.state_id = strdup(aspect_mapping->id->str); syslog_libbidib(LOG_NOTICE, "Set signal: %s on board: %s (0x%02x 0x%02x " "0x%02x 0x00) to aspect: %s with action id: %d", diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index c5a43ef..76c4864 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -70,9 +70,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, if (reverser_state->data.state_id != NULL) { free(reverser_state->data.state_id); - reverser_state->data.state_id = NULL; } - reverser_state->data.state_id = strdup(mapping->id->str); switch (value[0]) { case '0': From c302abbc37dbb5ad0982c54f67a15a9f22510f3e Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Tue, 3 Dec 2024 14:45:57 +0100 Subject: [PATCH 42/51] minor fix one memleak, heartbeat thread join, const. --- src/highlevel/bidib_highlevel_util.c | 3 +++ src/state/bidib_state_free.c | 3 +++ src/state/bidib_state_setter.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 8a8a6c3..9ac55b2 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -238,6 +238,9 @@ void bidib_stop(void) { pthread_join(bidib_autoflush_thread, NULL); } } + if (bidib_heartbeat_thread != 0) { + pthread_join(bidib_heartbeat_thread, NULL); + } syslog_libbidib(LOG_NOTICE, "libbidib stopping: threads have joined"); bidib_serial_port_close(); syslog_libbidib(LOG_NOTICE, "libbidib stopping: Serial port closed"); diff --git a/src/state/bidib_state_free.c b/src/state/bidib_state_free.c index c5fc74b..cb85101 100644 --- a/src/state/bidib_state_free.c +++ b/src/state/bidib_state_free.c @@ -304,6 +304,9 @@ void bidib_state_free_single_board(t_bidib_board board) { if (tmp.id != NULL) { g_string_free(tmp.id, TRUE); } + if (tmp.cv != NULL) { + g_string_free(tmp.cv, TRUE); + } } g_array_free(board.reversers, TRUE); board.reversers = NULL; diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 76c4864..8a5fb4b 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -49,7 +49,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, char *value = strndup((const char *)&value_list[length - value_len], value_len); // check whether the name corresponds to the CV of a reverser - t_bidib_reverser_mapping *mapping = + const t_bidib_reverser_mapping *mapping = bidib_state_get_reverser_mapping_ref_by_cv(node_address, name); if (mapping != NULL) { t_bidib_reverser_state *reverser_state = From 7187679b6b8b35ff592fcee68e6d5d4131b3b575 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 12:14:18 +0100 Subject: [PATCH 43/51] removed single-byte write and related functions --- include/highlevel/bidib_highlevel_util.h | 7 +-- src/highlevel/bidib_highlevel_util.c | 9 ++-- src/transmission/bidib_transmission_intern.h | 9 ---- src/transmission/bidib_transmission_send.c | 45 +++---------------- .../bidib_transmission_serial_port.c | 6 --- .../bidib_transmission_serial_port_intern.h | 8 +--- test/unit/bidib_feedback_tests.c | 6 +-- test/unit/bidib_highlevel_message_tests.c | 7 +-- test/unit/bidib_lowlevel_message_tests.c | 7 +-- test/unit/bidib_parallel_tests.c | 7 +-- test/unit/bidib_receive_tests.c | 6 +-- test/unit/bidib_send_tests.c | 6 +-- test/unit/bidib_state_tests.c | 7 +-- 13 files changed, 18 insertions(+), 112 deletions(-) diff --git a/include/highlevel/bidib_highlevel_util.h b/include/highlevel/bidib_highlevel_util.h index 8dbca7d..1214b6e 100644 --- a/include/highlevel/bidib_highlevel_util.h +++ b/include/highlevel/bidib_highlevel_util.h @@ -42,8 +42,6 @@ * * @param read a pointer to a function, which reads a byte from the connected * BiDiB interface. This function must not be blocking. - * @param write a pointer to a function, which sends a byte to the connected - * BiDiB interface. * @param write_n a pointer to a function, which sends n bytes to the connected * BiDiB interface. * @param config_dir the directory in which the config files are stored, use @@ -52,9 +50,8 @@ * automatic flushing is disabled. * @return 0 if configs are valid, otherwise 1. */ -int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), - void (*write_n)(uint8_t*, int32_t), const char *config_dir, - unsigned int flush_interval); +int bidib_start_pointer(uint8_t (*read)(int *), void (*write_n)(uint8_t*, int32_t), + const char *config_dir, unsigned int flush_interval); /** * Starts the system, handles the connection via a serial port. Also configures diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 9ac55b2..44b8337 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -134,10 +134,9 @@ static void bidib_init_threads(unsigned int flush_interval) { } } -int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), - void (*write_n)(uint8_t*, int32_t), const char *config_dir, - unsigned int flush_interval) { - if (read == NULL || write == NULL || (!bidib_lowlevel_debug_mode && config_dir == NULL)) { +int bidib_start_pointer(uint8_t (*read)(int *), void (*write_n)(uint8_t*, int32_t), + const char *config_dir, unsigned int flush_interval) { + if (read == NULL || write_n == NULL || (!bidib_lowlevel_debug_mode && config_dir == NULL)) { return 1; } int error = 0; @@ -158,7 +157,6 @@ int bidib_start_pointer(uint8_t (*read)(int *), void (*write)(uint8_t), } bidib_set_read_src(read); - bidib_set_write_dest(write); bidib_set_write_n_dest(write_n); bidib_init_threads(flush_interval); @@ -198,7 +196,6 @@ int bidib_start_serial(const char *device, const char *config_dir, unsigned int error = 1; } else { bidib_set_read_src(bidib_serial_port_read); - bidib_set_write_dest(bidib_serial_port_write); bidib_set_write_n_dest(bidib_serial_port_write_n); bidib_init_threads(flush_interval); diff --git a/src/transmission/bidib_transmission_intern.h b/src/transmission/bidib_transmission_intern.h index 8719a9b..45bb990 100644 --- a/src/transmission/bidib_transmission_intern.h +++ b/src/transmission/bidib_transmission_intern.h @@ -228,15 +228,6 @@ uint8_t *bidib_read_intern_message(void); */ void bidib_set_read_src(uint8_t (*read)(int *)); -/** - * Sets the output of libbidib, specifically the output - * which allows writing a single byte at a time. - * - * @param write a pointer to a function, which sends a byte to the connected - * BiDiB interface. - */ -void bidib_set_write_dest(void (*write)(uint8_t)); - /** * Sets the output of libbidib, specifically the output * which allows writing n bytes at a time. diff --git a/src/transmission/bidib_transmission_send.c b/src/transmission/bidib_transmission_send.c index c24c2f8..8d4fc5c 100644 --- a/src/transmission/bidib_transmission_send.c +++ b/src/transmission/bidib_transmission_send.c @@ -43,7 +43,6 @@ pthread_mutex_t bidib_send_buffer_mutex; -static void (*write_byte)(uint8_t); static void (*write_bytes)(uint8_t*, int32_t); volatile bool bidib_seq_num_enabled = true; @@ -52,14 +51,9 @@ static volatile uint8_t buffer[PACKET_BUFFER_SIZE]; static volatile uint8_t buffer_aux[PACKET_BUFFER_AUX_SIZE]; static volatile size_t buffer_index = 0; -void bidib_set_write_dest(void (*write)(uint8_t)) { - write_byte = write; - syslog_libbidib(LOG_INFO, "Write function was set"); -} - void bidib_set_write_n_dest(void (*write_n)(uint8_t*, int32_t)) { write_bytes = write_n; - syslog_libbidib(LOG_INFO, "Write_n function was set"); + syslog_libbidib(LOG_INFO, "write_bytes function was set"); } void bidib_state_packet_capacity(uint8_t max_capacity) { @@ -74,37 +68,6 @@ void bidib_state_packet_capacity(uint8_t max_capacity) { pthread_mutex_unlock(&bidib_send_buffer_mutex); } -static void bidib_send_byte(uint8_t b) { - if ((b == BIDIB_PKT_MAGIC) || (b == BIDIB_PKT_ESCAPE)) { - write_byte(BIDIB_PKT_ESCAPE); - b = b ^ (uint8_t) 0x20; - } - write_byte(b); -} - - -static void bidib_send_delimiter(void) { - write_byte(BIDIB_PKT_MAGIC); -} - -// Shall only be called with bidib_send_buffer_mutex locked. -static void bidib_flush_impl_old(void) { - if (buffer_index > 0) { - uint8_t crc = 0; - bidib_send_delimiter(); - for (size_t i = 0; i < buffer_index; i++) { - bidib_send_byte(buffer[i]); - crc = bidib_crc_array[buffer[i] ^ crc]; - } - bidib_send_byte(crc); - bidib_send_delimiter(); - // Could be optimized to use end-delimiter of last message also as - // start-delimiter for next one - buffer_index = 0; - } - syslog_libbidib(LOG_DEBUG, "Cache flushed"); -} - /** * Will flush the send cache, if possible in one go (as one batch); * if batching not possible, then send byte-per-byte. @@ -128,7 +91,8 @@ static void bidib_flush_impl(void) { if (buffer_index > 0) { uint8_t crc = 0; int32_t aux_index = 0; - buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv + // BIDIB_PKT_MAGIC marks the (starting) delimiter + buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; for (size_t i = 0; i < buffer_index; ++i) { // At most 2 more chars can be added in one loop iteration if (aux_index + 3 >= PACKET_BUFFER_AUX_SIZE) { @@ -163,7 +127,8 @@ static void bidib_flush_impl(void) { } else { buffer_aux[aux_index++] = crc; } - buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // send_delimiter equiv + // BIDIB_PKT_MAGIC marks the (end) delimiter + buffer_aux[aux_index++] = BIDIB_PKT_MAGIC; // Batch-write aux buffer and reset the buffer index. write_bytes((uint8_t*)buffer_aux, aux_index); diff --git a/src/transmission/bidib_transmission_serial_port.c b/src/transmission/bidib_transmission_serial_port.c index a6cdc46..1650d78 100644 --- a/src/transmission/bidib_transmission_serial_port.c +++ b/src/transmission/bidib_transmission_serial_port.c @@ -118,12 +118,6 @@ uint8_t bidib_serial_port_read(int *byte_read) { return buff[0]; } -void bidib_serial_port_write(uint8_t msg) { - if (write(fd, &msg, 1) != 1) { - syslog_libbidib(LOG_ERR, "Error while sending data via serial port (single byte write)"); - } -} - void bidib_serial_port_write_n(uint8_t *msg, int32_t len) { if (msg == NULL || len <= 0 || (write(fd, msg, len) != len)) { syslog_libbidib(LOG_ERR, "Error while sending data via serial port (%d-byte write)", len); diff --git a/src/transmission/bidib_transmission_serial_port_intern.h b/src/transmission/bidib_transmission_serial_port_intern.h index fb0c25c..4aa2b74 100644 --- a/src/transmission/bidib_transmission_serial_port_intern.h +++ b/src/transmission/bidib_transmission_serial_port_intern.h @@ -48,15 +48,9 @@ int bidib_serial_port_init(const char *device); */ int bidib_detect_baudrate(void); -/** - * Sends a byte via the serial port to the BiDiB interface. - * - * @param msg the byte. - */ -void bidib_serial_port_write(uint8_t msg); /** - * Sends multiple bytes via the serial port to the BiDiB interface. + * Sends n bytes via the serial port to the BiDiB interface. * * @param msg the start address of bytes * @param len the number of bytes to send (msg[0]...msg[len-1]). diff --git a/test/unit/bidib_feedback_tests.c b/test/unit/bidib_feedback_tests.c index 0d97d4a..a5b8a71 100644 --- a/test/unit/bidib_feedback_tests.c +++ b/test/unit/bidib_feedback_tests.c @@ -66,10 +66,6 @@ static uint8_t read_byte(int *read_byte) { } } -static void write_byte(uint8_t byte) { - output_buffer[output_index++] = byte; -} - static void write_bytes(uint8_t* msg, int32_t len) { if (msg != NULL && len > 0) { for (int32_t i = 0; i < len; ++i) { @@ -526,7 +522,7 @@ static void feedback_reverser_state(void **state __attribute__((unused))) { int main(void) { test_setup(); - bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 250); + bidib_start_pointer(&read_byte, &write_bytes, "../test/unit/state_tests_config", 250); syslog_libbidib(LOG_INFO, "bidib_feedback_tests: Feedback tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(feedback_system_error), diff --git a/test/unit/bidib_highlevel_message_tests.c b/test/unit/bidib_highlevel_message_tests.c index 3b8c9cd..e074699 100644 --- a/test/unit/bidib_highlevel_message_tests.c +++ b/test/unit/bidib_highlevel_message_tests.c @@ -49,11 +49,6 @@ static uint8_t read_byte(int *read_byte) { return 0x00; } -static void write_byte(uint8_t msg_byte) { - output_buffer[output_index] = msg_byte; - output_index++; -} - static void write_bytes(uint8_t* msg, int32_t len) { if (msg != NULL && len > 0) { for (int32_t i = 0; i < len; ++i) { @@ -223,7 +218,7 @@ static void request_reverser_update_correctly(void **state __attribute__((unused int main(void) { bidib_set_lowlevel_debug_mode(true); - if (!bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 0)) { + if (!bidib_start_pointer(&read_byte, &write_bytes, "../test/unit/state_tests_config", 0)) { set_all_boards_and_trains_connected(); syslog_libbidib(LOG_INFO, "bidib_highlevel_message_tests: Highlevel message tests started"); const struct CMUnitTest tests[] = { diff --git a/test/unit/bidib_lowlevel_message_tests.c b/test/unit/bidib_lowlevel_message_tests.c index 1e6197f..6fb27e1 100644 --- a/test/unit/bidib_lowlevel_message_tests.c +++ b/test/unit/bidib_lowlevel_message_tests.c @@ -45,11 +45,6 @@ static uint8_t read_byte(int *read_byte) { return 0x00; } -static void write_byte(uint8_t msg_byte) { - output_buffer[output_index] = msg_byte; - output_index++; -} - static void write_bytes(uint8_t* msg, int32_t len) { if (msg != NULL && len > 0) { for (int32_t i = 0; i < len; ++i) { @@ -182,7 +177,7 @@ static void bm_mirror_multiple_correctly_send(void **state __attribute__((unused int main(void) { bidib_set_lowlevel_debug_mode(true); - bidib_start_pointer(&read_byte, &write_byte, &write_bytes, NULL, 0); + bidib_start_pointer(&read_byte, &write_bytes, NULL, 0); syslog_libbidib(LOG_INFO, "bidib_lowlevel_message_tests: %s", "Lowlevel message tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(vendor_data_set_correctly_send), diff --git a/test/unit/bidib_parallel_tests.c b/test/unit/bidib_parallel_tests.c index e682da9..88d2e54 100644 --- a/test/unit/bidib_parallel_tests.c +++ b/test/unit/bidib_parallel_tests.c @@ -52,11 +52,6 @@ static uint8_t read_byte(int *read_byte) { return 0x00; } -static void write_byte(uint8_t msg_byte) { - output_buffer[output_index] = msg_byte; - output_index++; -} - static void write_bytes(uint8_t* msg, int32_t len) { if (msg != NULL && len > 0) { for (int32_t i = 0; i < len; ++i) { @@ -300,7 +295,7 @@ static void parallel_all(void **state __attribute__((unused))) { int main(void) { bidib_set_lowlevel_debug_mode(true); - if (!bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 0)) { + if (!bidib_start_pointer(&read_byte, &write_bytes, "../test/unit/state_tests_config", 0)) { set_all_boards_and_trains_connected(); syslog_libbidib(LOG_INFO, "bidib_parallel_tests: Parallel tests started"); const struct CMUnitTest tests[] = { diff --git a/test/unit/bidib_receive_tests.c b/test/unit/bidib_receive_tests.c index fca580e..013bb76 100644 --- a/test/unit/bidib_receive_tests.c +++ b/test/unit/bidib_receive_tests.c @@ -51,10 +51,6 @@ static uint8_t read_byte(int *read_byte) { } } -static void write_byte(uint8_t byte __attribute__((unused))) { - return; -} - static void write_bytes(uint8_t* msg __attribute__((unused)), int32_t len __attribute__((unused))) { return; } @@ -134,7 +130,7 @@ static void corrupted_packets_are_discarded_and_additional_pkt_magic_ignored(voi int main(void) { test_setup(); bidib_set_lowlevel_debug_mode(true); - bidib_start_pointer(&read_byte, &write_byte, &write_bytes, NULL, 250); + bidib_start_pointer(&read_byte, &write_bytes, NULL, 250); syslog_libbidib(LOG_INFO, "bidib_receive_tests: %s", "Receive tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(packet_with_two_messages_correctly_handled), diff --git a/test/unit/bidib_send_tests.c b/test/unit/bidib_send_tests.c index 9d6939a..4baf602 100644 --- a/test/unit/bidib_send_tests.c +++ b/test/unit/bidib_send_tests.c @@ -100,10 +100,6 @@ static void test_setup() { input_buffer[49] = BIDIB_PKT_MAGIC; } -static void write_byte(uint8_t msg_byte) { - output_buffer[output_index++] = msg_byte; -} - static void write_bytes(uint8_t* msg, int32_t len) { if (msg != NULL && len > 0) { for (int32_t i = 0; i < len; ++i) { @@ -319,7 +315,7 @@ static void received_stall_zero_flushes_node_and_subnodes(void **state __attribu int main(void) { test_setup(); bidib_set_lowlevel_debug_mode(true); - bidib_start_pointer(&read_byte, &write_byte, &write_bytes, NULL, 0); + bidib_start_pointer(&read_byte, &write_bytes, NULL, 0); syslog_libbidib(LOG_INFO, "bidib_send_tests: %s", "Send tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(first_message_is_buffered), diff --git a/test/unit/bidib_state_tests.c b/test/unit/bidib_state_tests.c index 1854bae..bcbb64b 100644 --- a/test/unit/bidib_state_tests.c +++ b/test/unit/bidib_state_tests.c @@ -76,11 +76,6 @@ static uint8_t read_byte(int *read_byte) { } } -static void write_byte(uint8_t byte) { - static unsigned int output_index = 0; - output_buffer[output_index++] = byte; -} - static void write_bytes(uint8_t* msg, int32_t len) { static unsigned int output_index = 0; if (msg != NULL && len > 0) { @@ -402,7 +397,7 @@ static void reverser_updates_state_correctly(void **state __attribute__((unused) int main(void) { test_setup(); - bidib_start_pointer(&read_byte, &write_byte, &write_bytes, "../test/unit/state_tests_config", 250); + bidib_start_pointer(&read_byte, &write_bytes, "../test/unit/state_tests_config", 250); syslog_libbidib(LOG_INFO, "bidib_state_tests: %s", "State tests started"); const struct CMUnitTest tests[] = { cmocka_unit_test(sys_reset_send_after_connection_is_established), From bfcf8f133e1c6b155a23ecd02a49e75563832397 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 12:20:57 +0100 Subject: [PATCH 44/51] physical testsuite driveTo cleanup a little --- test/physical/test_common.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/test/physical/test_common.c b/test/physical/test_common.c index 4b218a1..0b875ff 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -181,8 +181,10 @@ bool testsuite_trainReady(const char *train, const char *segment) { } } -void testsuite_driveTo_old(const char *segment, int speed, const char *train) { - syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d", train, segment, speed); +void testsuite_driveTo_legacy(const char *segment, int speed, const char *train) { + // This driveTo impl queries the train position directly. + // Kept for testing purposes, but deprecated. + printf("testsuite: Drive %s to %s at speed %d\n", train, segment, speed); bidib_set_train_speed(train, speed, "master"); bidib_flush(); long counter = 0; @@ -193,8 +195,7 @@ void testsuite_driveTo_old(const char *segment, int speed, const char *train) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); bidib_free_train_position_query(trainPosition); - syslog(LOG_WARNING, - "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", + printf("testsuite: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } @@ -204,8 +205,7 @@ void testsuite_driveTo_old(const char *segment, int speed, const char *train) { if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - syslog(LOG_WARNING, - "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", + printf("testsuite: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); } @@ -217,8 +217,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { // This driveTo impl works by querying the segment state repeatedly, not the train position. // -> bidib_get_segment_state does not need to lock the trainstate rwlock, thus hopefully // reducing lock contention. - syslog(LOG_WARNING, "libbidib test: Drive %s to %s at speed %d", train, segment, speed); - printf("libbidib test: Drive %s to %s at speed %d\n", train, segment, speed); + printf("testsuite: Drive %s to %s at speed %d\n", train, segment, speed); bidib_set_train_speed(train, speed, "master"); bidib_flush(); t_bidib_dcc_address_query tr_dcc_addr = bidib_get_train_dcc_addr(train); @@ -233,10 +232,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); bidib_free_segment_state_query(seg_query); - syslog(LOG_WARNING, - "libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", - train, segment, speed, tv.tv_sec, tv.tv_nsec); - printf("libbidib test: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", + printf("testsuite: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } @@ -246,10 +242,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - //syslog(LOG_WARNING, - // "libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", - // train, segment, speed, tv.tv_sec, tv.tv_nsec); - printf("libbidib test: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", + printf("testsuite: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", train, segment, speed, tv.tv_sec, tv.tv_nsec); } From 76a35f4c2468a6403f0b3c5a214ea95ed75c5a5e Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 12:32:42 +0100 Subject: [PATCH 45/51] cleanup heartbeat log, and remove ineffective field specifier in printing time --- src/highlevel/bidib_highlevel_util.c | 151 +----------------- src/transmission/bidib_transmission_receive.c | 2 +- test/physical/test_common.c | 8 +- 3 files changed, 9 insertions(+), 152 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 44b8337..9fe6e9d 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -266,154 +266,11 @@ void syslog_libbidib(int priority, const char *format, ...) { } void *bidib_heartbeat_log(void *par __attribute__((unused))) { - uint32_t iters = 0; - uint32_t bidib_state_trains_rwlock_lockedcount = 0; - uint32_t trackstate_accessories_mutex_lockedcount = 0; - uint32_t trackstate_peripherals_mutex_lockedcount = 0; - uint32_t trackstate_segments_mutex_lockedcount = 0; - uint32_t trackstate_reversers_mutex_lockedcount = 0; - uint32_t trackstate_trains_mutex_lockedcount = 0; - uint32_t trackstate_boosters_mutex_lockedcount = 0; - uint32_t trackstate_track_outputs_mutex_lockedcount = 0; - uint32_t bidib_state_boards_rwlock_lockedcount = 0; - - struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); - while (bidib_running) { - //sleep(2); - //struct timespec tv; - //clock_gettime(CLOCK_MONOTONIC, &tv); - /////TODO: Back to debug? - //syslog_libbidib(LOG_WARNING, "Heartbeat, time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); - - // check the status of locked/unlocked mutexes. - iters++; - - if (pthread_rwlock_trywrlock(&bidib_state_trains_rwlock) == 0) { - pthread_rwlock_unlock(&bidib_state_trains_rwlock); - } else { - ++bidib_state_trains_rwlock_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_accessories_mutex) == 0) { - pthread_mutex_unlock(&trackstate_accessories_mutex); - } else { - ++trackstate_accessories_mutex_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_peripherals_mutex) == 0) { - pthread_mutex_unlock(&trackstate_peripherals_mutex); - } else { - ++trackstate_peripherals_mutex_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_segments_mutex) == 0) { - pthread_mutex_unlock(&trackstate_segments_mutex); - } else { - ++trackstate_segments_mutex_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_reversers_mutex) == 0) { - pthread_mutex_unlock(&trackstate_reversers_mutex); - } else { - ++trackstate_reversers_mutex_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_trains_mutex) == 0) { - pthread_mutex_unlock(&trackstate_trains_mutex); - } else { - ++trackstate_trains_mutex_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_boosters_mutex) == 0) { - pthread_mutex_unlock(&trackstate_boosters_mutex); - } else { - ++trackstate_boosters_mutex_lockedcount; - } - - if (pthread_mutex_trylock(&trackstate_track_outputs_mutex) == 0) { - pthread_mutex_unlock(&trackstate_track_outputs_mutex); - } else { - ++trackstate_track_outputs_mutex_lockedcount; - } - - if (pthread_rwlock_trywrlock(&bidib_state_boards_rwlock) == 0) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); - } else { - ++bidib_state_boards_rwlock_lockedcount; - } - - usleep(5000); // 0.005s (1/100th) - //usleep(10000); // 0.01s (1/100th) - - // Report the mutex statistics every 2 seconds - if (iters == 400) { - clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t elapsed_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; - - syslog_libbidib(LOG_WARNING, "Mutex statistics report for last 2 seconds (actual elapsed time: %llu, rounded to seconds: %llu):\n", - elapsed_us, elapsed_us / 1000000); - syslog_libbidib(LOG_WARNING, "bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", - ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_accessories_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_accessories_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_peripherals_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_peripherals_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_segments_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_segments_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_reversers_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_reversers_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_trains_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_trains_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_boosters_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_boosters_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "trackstate_track_outputs_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_track_outputs_mutex_lockedcount / (float) iters)*100.0f); - syslog_libbidib(LOG_WARNING, "bidib_state_boards_rwlock: Wr-Locked %.2f percent of the time\n", - ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); - //printf("\n\n"); - - /**/ - printf("Libbidib: Mutex statistics report for last 2 seconds (actual elapsed time: %llu, rounded to seconds: %llu):\n", - elapsed_us, elapsed_us / 1000000); - printf("bidib_state_trains_rwlock: Wr-Locked %.2f percent of the time\n", - ((float) bidib_state_trains_rwlock_lockedcount / (float) iters)*100.0f); - printf("trackstate_accessories_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_accessories_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_peripherals_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_peripherals_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_segments_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_segments_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_reversers_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_reversers_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_trains_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_trains_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_boosters_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_boosters_mutex_lockedcount / (float) iters)*100.0f); - printf("trackstate_track_outputs_mutex: Locked %.2f percent of the time\n", - ((float) trackstate_track_outputs_mutex_lockedcount / (float) iters)*100.0f); - printf("bidib_state_boards_rwlock: Wr-Locked %.2f percent of the time\n", - ((float) bidib_state_boards_rwlock_lockedcount / (float) iters)*100.0f); - printf("\n\n"); - /**/ - iters = 0; - bidib_state_trains_rwlock_lockedcount = 0; - trackstate_accessories_mutex_lockedcount = 0; - trackstate_peripherals_mutex_lockedcount = 0; - trackstate_segments_mutex_lockedcount = 0; - trackstate_reversers_mutex_lockedcount = 0; - trackstate_trains_mutex_lockedcount = 0; - trackstate_boosters_mutex_lockedcount = 0; - trackstate_track_outputs_mutex_lockedcount = 0; - bidib_state_boards_rwlock_lockedcount = 0; - clock_gettime(CLOCK_MONOTONIC_RAW, &start); - } - + sleep(2); + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + syslog_libbidib(LOG_WARNING, "Heartbeat, time %ld.%.ld", tv.tv_sec, tv.tv_nsec); } - - ///TODO: stopping -> report the remainder - - return NULL; } \ No newline at end of file diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index dfec61f..1c2a584 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -793,7 +793,7 @@ static void bidib_receive_packet(void) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - syslog_libbidib(LOG_DEBUG, "Received packet, at time %ld.%.5ld", tv.tv_sec, tv.tv_nsec); + syslog_libbidib(LOG_DEBUG, "Received packet, at time %ld.%.ld", tv.tv_sec, tv.tv_nsec); if (crc == 0x00) { // Split packet in messages and add them to queue, exclude crc sum diff --git a/test/physical/test_common.c b/test/physical/test_common.c index 0b875ff..e1594c1 100644 --- a/test/physical/test_common.c +++ b/test/physical/test_common.c @@ -195,7 +195,7 @@ void testsuite_driveTo_legacy(const char *segment, int speed, const char *train) struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); bidib_free_train_position_query(trainPosition); - printf("testsuite: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld", + printf("testsuite: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } @@ -205,7 +205,7 @@ void testsuite_driveTo_legacy(const char *segment, int speed, const char *train) if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - printf("testsuite: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld", + printf("testsuite: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.ld", train, segment, speed, tv.tv_sec, tv.tv_nsec); } @@ -232,7 +232,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); bidib_free_segment_state_query(seg_query); - printf("testsuite: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.5ld\n", + printf("testsuite: Drive %s to %s at speed %d - REACHED TARGET - detected at time %ld.%.ld\n", train, segment, speed, tv.tv_sec, tv.tv_nsec); return; } @@ -242,7 +242,7 @@ void testsuite_driveTo(const char *segment, int speed, const char *train) { if (counter++ % 8 == 0) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - printf("testsuite: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.5ld\n", + printf("testsuite: Drive %s to %s at speed %d - waiting for train to arrive, time %ld.%.ld\n", train, segment, speed, tv.tv_sec, tv.tv_nsec); } From 98bec1b304cf46551cf7658a9a1340b82c585791 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 12:53:03 +0100 Subject: [PATCH 46/51] adjusted log level on bidib_state_lc_stat and some minor adjustments in bidib_state_setter overall --- src/state/bidib_state_setter.c | 42 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 8a5fb4b..3785e11 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -37,7 +37,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, - const uint8_t *const value_list, unsigned int action_id) { + const uint8_t *const value_list, unsigned int action_id) { // For bidib_state_get_reverser_state_ref (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); // For bidib_state_get_reverser_mapping_ref_by_cv @@ -45,7 +45,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, uint8_t name_len = value_list[0]; char *name = strndup((const char *)&value_list[1], name_len); - uint8_t value_len = value_list[name_len + 1]; + uint8_t value_len = value_list[name_len + 1]; char *value = strndup((const char *)&value_list[length - value_len], value_len); // check whether the name corresponds to the CV of a reverser @@ -55,14 +55,14 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, t_bidib_reverser_state *reverser_state = bidib_state_get_reverser_state_ref(mapping->id->str); if (reverser_state == NULL) { + pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Feedback for vendor-specific configuration %s (value %s) " "with node address 0x%02x 0x%02x 0x%02x 0x00 has been discarded, " "the reverser state is NULL", name, value, node_address.top, node_address.sub, node_address.subsub); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_mutex_unlock(&trackstate_reversers_mutex); free(name); free(value); return; @@ -160,17 +160,18 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb } if (execution == BIDIB_ACC_STATE_ERROR) { - syslog_libbidib(LOG_ERR, "Feedback for action id %d: %s accessory: %s aspect: %s error code: 0x%02x", + syslog_libbidib(LOG_ERR, + "Feedback for action id %d: %s accessory: %s aspect: %s error code: 0x%02x", action_id, (point) ? "Point" : "Signal", accessory_mapping->id->str, aspect_mapping->id->str, wait); } else { const bool target_state_reached = (execution & 0x01) == 0x00; - const bool target_state_verified = (execution & 0x02) == 0x00; + const bool target_state_verified = (execution & 0x02) == 0x00; const float wait_time = (target_state_reached) ? 0.0 : (wait & 0x80) ? (wait & 0x3f) : ((float) (wait & 0x3f)) * 0.1; syslog_libbidib(LOG_INFO, "Feedback for action id %d: %s accessory: %s execution: %s%s reached%s " - "verified with wait time: %.1fs", + "verified with wait time: %.1fs", action_id, (point) ? "Point" : "Signal", accessory_mapping->id->str, aspect_mapping->id->str, (target_state_reached) ? "" : " not", @@ -432,11 +433,11 @@ void bidib_state_cs_accessory(t_bidib_node_address node_address, t_bidib_cs_accessory_mod params) { bool point; const t_bidib_dcc_accessory_mapping *const accessory_mapping = - bidib_state_get_dcc_accessory_mapping_ref_by_dccaddr(node_address, params.dcc_address, &point); + bidib_state_get_dcc_accessory_mapping_ref_by_dccaddr(node_address, params.dcc_address, &point); t_bidib_dcc_accessory_state *accessory_state; if (accessory_mapping != NULL && - (accessory_state = bidib_state_get_dcc_accessory_state_ref(accessory_mapping->id->str, - point)) != NULL) { + (accessory_state = + bidib_state_get_dcc_accessory_state_ref(accessory_mapping->id->str, point)) != NULL) { if (accessory_state->data.state_id != NULL) { free(accessory_state->data.state_id); } @@ -495,7 +496,7 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p "Aspect 0x%02x of peripheral %s is not mapped in config files", portstat, peripheral_mapping->id->str); } else { - syslog_libbidib(LOG_INFO, + syslog_libbidib(LOG_DEBUG, "Feedback for action id %d: Peripheral: %s has aspect: %s (0x%02x)", action_id, peripheral_mapping->id->str, aspect_mapping->id->str, portstat); } @@ -521,7 +522,7 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p pthread_rwlock_rdlock(&bidib_state_boards_rwlock); const t_bidib_peripheral_mapping *const peripheral_mapping = - bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); + bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); if (peripheral_mapping != NULL && (peripheral_state = bidib_state_get_peripheral_state_ref(peripheral_mapping->id->str)) != NULL) { if (time & (1 << 7)) { @@ -553,7 +554,7 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p void bidib_state_log_train_detect(bool detected, const t_bidib_dcc_address *const dcc_address, const t_bidib_segment_state_intern *const segment_state) { const t_bidib_train_state_intern *const train_state = - bidib_state_get_train_state_ref_by_dccaddr(*dcc_address); + bidib_state_get_train_state_ref_by_dccaddr(*dcc_address); if (detected) { if (train_state == NULL) { syslog_libbidib(LOG_NOTICE, @@ -597,10 +598,9 @@ void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool segment_state->occupied = occ; if (!occ && segment_state->dcc_addresses->len > 0) { for (size_t j = 0; j < segment_state->dcc_addresses->len; j++) { - const t_bidib_dcc_address *const dcc_address = &g_array_index(segment_state->dcc_addresses, - t_bidib_dcc_address, j); - bidib_state_log_train_detect(false, dcc_address, - segment_state); + const t_bidib_dcc_address *const dcc_address = + &g_array_index(segment_state->dcc_addresses, t_bidib_dcc_address, j); + bidib_state_log_train_detect(false, dcc_address, segment_state); } g_array_remove_range(segment_state->dcc_addresses, 0, segment_state->dcc_addresses->len); @@ -631,7 +631,7 @@ void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, for (size_t i = 0; i < size; i++) { if (number + i < 255) { segment_state = bidib_state_get_segment_state_ref_by_nodeaddr( - node_address, (uint8_t) (number + i)); + node_address, (uint8_t) (number + i)); if (segment_state != NULL) { if (data[i / 8] & (1 << i % 8)) { segment_state->occupied = true; @@ -673,15 +673,15 @@ void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_v t_bidib_segment_state_intern *segment_state; for (size_t i = 0; i < board->segments->len; i++) { const t_bidib_segment_mapping *const segment_mapping = - &g_array_index(board->segments, t_bidib_segment_mapping, i); + &g_array_index(board->segments, t_bidib_segment_mapping, i); segment_state = bidib_state_get_segment_state_ref(segment_mapping->id->str); segment_state->confidence.conf_void = (conf_void != 0); segment_state->confidence.freeze = (freeze != 0); segment_state->confidence.nosignal = (nosignal != 0); } - const t_bidib_bm_confidence_level confidence_level = - bidib_bm_confidence_to_level((t_bidib_segment_state_confidence) {conf_void, freeze, nosignal}); + const t_bidib_bm_confidence_level confidence_level = bidib_bm_confidence_to_level( + (t_bidib_segment_state_confidence) {conf_void, freeze, nosignal}); char *confidence_name = NULL; switch (confidence_level) { case (BIDIB_BM_CONFIDENCE_ACCURATE): From e296092b45f3ac7e5c3809dc811e503003767002 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 13:03:13 +0100 Subject: [PATCH 47/51] formatting/whitespace --- src/transmission/bidib_transmission_receive.c | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 1c2a584..7438510 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -264,8 +264,7 @@ static void bidib_log_boost_stat_error(const uint8_t *const message, GString *fault_name = g_string_new(""); if (error_type <= 0x84) { - g_string_printf(fault_name, "%s", - bidib_boost_state_string_mapping[error_type]); + g_string_printf(fault_name, "%s", bidib_boost_state_string_mapping[error_type]); } else { g_string_printf(fault_name, "UNKNOWN"); } @@ -284,9 +283,8 @@ static void bidib_log_boost_stat_okay(const uint8_t *const message, unsigned int msg_type = message[data_index]; GString *msg_name = g_string_new(""); - if (msg_type <= 0x84) { - g_string_printf(msg_name, "%s", - bidib_boost_state_string_mapping[msg_type]); + if (msg_type <= 0x84) { + g_string_printf(msg_name, "%s", bidib_boost_state_string_mapping[msg_type]); } else { g_string_printf(msg_name, "UNKNOWN"); } @@ -724,25 +722,34 @@ static void bidib_split_packet(const uint8_t *const buffer, size_t buffer_size) } } clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t msg_read_in_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + uint64_t msg_read_in_us = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_nsec - start.tv_nsec) / 1000; clock_gettime(CLOCK_MONOTONIC_RAW, &start); unsigned int action_id = bidib_node_state_update(addr_stack, type); clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t node_update_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + uint64_t node_update_us = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_nsec - start.tv_nsec) / 1000; clock_gettime(CLOCK_MONOTONIC_RAW, &start); bidib_handle_received_message(message, type, addr_stack, msg_seqnum, action_id); clock_gettime(CLOCK_MONOTONIC_RAW, &end); - uint64_t handle_receive_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; + uint64_t handle_receive_us = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_nsec - start.tv_nsec) / 1000; const uint64_t slow_processing_threshold_us = 100000; // 0.1 s if (msg_read_in_us + node_update_us + handle_receive_us > slow_processing_threshold_us) { // In case the processing steps above take above the specified threshold, // i.e., longer than expected, log the time taken for each of the three steps. syslog_libbidib(LOG_ERR, - "bidib_split_packet took longer than threshold %llu us for message of type %s", + "bidib_split_packet took longer than threshold %llu us for msg of type %s", slow_processing_threshold_us, bidib_message_string_mapping[type]); - syslog_libbidib(LOG_WARNING, "bidib_split_packet msg-read-in: %llu us", msg_read_in_us); - syslog_libbidib(LOG_WARNING, "bidib_split_packet node-update: %llu us", node_update_us); - syslog_libbidib(LOG_WARNING, "bidib_split_packet handle-receive: %llu us", handle_receive_us); + syslog_libbidib(LOG_WARNING, + "bidib_split_packet msg-read-in: %llu us", + msg_read_in_us); + syslog_libbidib(LOG_WARNING, + "bidib_split_packet node-update: %llu us", + node_update_us); + syslog_libbidib(LOG_WARNING, + "bidib_split_packet handle-receive: %llu us", + handle_receive_us); } } } From 7f217006bf95dcade33222ef1674404089133cf0 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 13:25:50 +0100 Subject: [PATCH 48/51] heartbeat log sleep partitioned into smaller sleeps, bidib_stop logs and order improved --- src/highlevel/bidib_highlevel_util.c | 31 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index 9fe6e9d..acc8789 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -221,19 +221,19 @@ void bidib_stop(void) { // close the track bidib_set_track_output_state_all(BIDIB_CS_SOFTSTOP); bidib_flush(); - usleep(300000); + usleep(300000); // 0.3s bidib_state_reset_train_params(); bidib_flush(); - usleep(300000); + usleep(300000); // 0.3s bidib_set_track_output_state_all(BIDIB_CS_OFF); bidib_flush(); - syslog_libbidib(LOG_NOTICE, "libbidib stopping: waiting for threads to join"); bidib_running = false; + syslog_libbidib(LOG_NOTICE, "libbidib stopping: waiting for threads to join"); if (bidib_receiver_thread != 0) { pthread_join(bidib_receiver_thread, NULL); - if (bidib_autoflush_thread != 0) { - pthread_join(bidib_autoflush_thread, NULL); - } + } + if (bidib_autoflush_thread != 0) { + pthread_join(bidib_autoflush_thread, NULL); } if (bidib_heartbeat_thread != 0) { pthread_join(bidib_heartbeat_thread, NULL); @@ -250,10 +250,10 @@ void bidib_stop(void) { bidib_uplink_intern_queue_free(); syslog_libbidib(LOG_NOTICE, "libbidib stopping: Uplink intern queue freed"); bidib_state_free(); - syslog_libbidib(LOG_NOTICE, "libbidib stopping: Uplink queue freed"); + syslog_libbidib(LOG_NOTICE, "libbidib stopping: State freed"); syslog_libbidib(LOG_NOTICE, "libbidib stopped"); closelog(); - usleep(500000); // wait for thread clean up + usleep(500000); // 0.5s, wait for thread clean up } } @@ -267,10 +267,21 @@ void syslog_libbidib(int priority, const char *format, ...) { void *bidib_heartbeat_log(void *par __attribute__((unused))) { while (bidib_running) { - sleep(2); struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); - syslog_libbidib(LOG_WARNING, "Heartbeat, time %ld.%.ld", tv.tv_sec, tv.tv_nsec); + syslog_libbidib(LOG_INFO, "Heartbeat, time %ld.%.ld", tv.tv_sec, tv.tv_nsec); + for (int i = 0; i < 20; i++) { + // 0.1s + usleep(100000); + if (!bidib_running) { + break; + } + } } + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + syslog_libbidib(LOG_INFO, + "Heartbeat exits as libbidib is stopping, time %ld.%.ld", + tv.tv_sec, tv.tv_nsec); return NULL; } \ No newline at end of file From 0f784e69ae6807a5144ca964b81c3932c321090c Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 13:26:56 +0100 Subject: [PATCH 49/51] remove ineffective format specifiers (%.9 has no effect on integers, only on floats/reals) --- src/state/bidib_state.c | 4 ++-- src/state/bidib_state_setter.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 61e15d8..1a1d474 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -708,14 +708,14 @@ void bidib_state_update_train_available(void) { (query.orientation_is_left ? BIDIB_TRAIN_ORIENTATION_LEFT : BIDIB_TRAIN_ORIENTATION_RIGHT); if (train_state->on_track == false) { - syslog_libbidib(LOG_NOTICE, "Train %s detected, orientated %s, at time %d.%.9ld", + syslog_libbidib(LOG_NOTICE, "Train %s detected, orientated %s, at time %d.%.ld", train_state->id->str, query.orientation_is_left ? "left" : "right", tv.tv_sec, tv.tv_nsec); } train_state->on_track = true; } else { if (train_state->on_track == true) { - syslog_libbidib(LOG_WARNING, "Train %s lost, at time %d.%.9ld", + syslog_libbidib(LOG_WARNING, "Train %s lost, at time %d.%.ld", train_state->id->str, tv.tv_sec, tv.tv_nsec); } train_state->on_track = false; diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index 3d65617..b3875af 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -562,13 +562,13 @@ void bidib_state_log_train_detect(bool detected, const t_bidib_dcc_address *cons if (train_state == NULL) { syslog_libbidib(LOG_NOTICE, "Segment: %s is being entered by: unknown train (0x%02x%02x) " - "with %s orientation, at time %d.%.9ld", + "with %s orientation, at time %d.%.ld", segment_state->id->str, dcc_address->addrh, dcc_address->addrl, dcc_address->type == 0 ? "left" : "right", tv.tv_sec, tv.tv_nsec); } else { syslog_libbidib(LOG_NOTICE, "Segment: %s is being entered by: %s with %s " - "orientation, at time %d.%.9ld", + "orientation, at time %d.%.ld", segment_state->id->str, train_state->id->str, train_state->orientation == BIDIB_TRAIN_ORIENTATION_LEFT ? "left" : "right", tv.tv_sec, tv.tv_nsec); @@ -577,13 +577,13 @@ void bidib_state_log_train_detect(bool detected, const t_bidib_dcc_address *cons if (train_state == NULL) { syslog_libbidib(LOG_NOTICE, "Segment: %s is being exited by: unknown train (0x%02x%02x) " - "with %s orientation, at time %d.%.9ld", + "with %s orientation, at time %d.%.ld", segment_state->id->str, dcc_address->addrh, dcc_address->addrl, dcc_address->type == 0 ? "left" : "right", tv.tv_sec, tv.tv_nsec); } else { syslog_libbidib(LOG_NOTICE, "Segment: %s is being exited by: %s with %s " - "orientation, at time %d.%.9ld", + "orientation, at time %d.%.ld", segment_state->id->str, train_state->id->str, train_state->orientation == BIDIB_TRAIN_ORIENTATION_LEFT ? "left" : "right", tv.tv_sec, tv.tv_nsec); From 8ea99592487dccc13cda9fe61d910825ed133f40 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 13:32:45 +0100 Subject: [PATCH 50/51] read-write locks renamed to be less confusing --- src/highlevel/bidib_highlevel_admin.c | 24 +-- src/highlevel/bidib_highlevel_getter.c | 116 +++++++------- src/highlevel/bidib_highlevel_intern.h | 6 +- src/highlevel/bidib_highlevel_setter.c | 142 +++++++++--------- src/highlevel/bidib_highlevel_util.c | 8 +- src/lowlevel/bidib_lowlevel_intern.h | 4 +- src/lowlevel/bidib_lowlevel_system.c | 4 +- src/lowlevel/bidib_lowlevel_track.c | 8 +- src/state/bidib_state.c | 44 +++--- src/state/bidib_state_getter.c | 14 +- src/state/bidib_state_getter_intern.h | 36 ++--- src/state/bidib_state_intern.h | 12 +- src/state/bidib_state_setter.c | 58 +++---- src/state/bidib_state_setter_intern.h | 8 +- src/transmission/bidib_transmission_receive.c | 46 +++--- test/unit/bidib_highlevel_message_tests.c | 10 +- test/unit/bidib_parallel_tests.c | 4 +- 17 files changed, 272 insertions(+), 272 deletions(-) diff --git a/src/highlevel/bidib_highlevel_admin.c b/src/highlevel/bidib_highlevel_admin.c index c93fd3b..a35865c 100644 --- a/src/highlevel/bidib_highlevel_admin.c +++ b/src/highlevel/bidib_highlevel_admin.c @@ -42,7 +42,7 @@ int bidib_ping(const char *board, uint8_t ping_byte) { return 1; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { unsigned int action_id = bidib_get_and_incr_action_id(); @@ -52,11 +52,11 @@ int bidib_ping(const char *board, uint8_t ping_byte) { tmp_board->node_addr.top, tmp_board->node_addr.sub, tmp_board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = tmp_board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_sys_ping(tmp_addr, ping_byte, action_id); return 0; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return 1; } @@ -66,7 +66,7 @@ int bidib_identify(const char *board, uint8_t state) { return 1; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { unsigned int action_id = bidib_get_and_incr_action_id(); @@ -76,11 +76,11 @@ int bidib_identify(const char *board, uint8_t state) { tmp_board->node_addr.top, tmp_board->node_addr.sub, tmp_board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = tmp_board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_sys_identify(tmp_addr, state, action_id); return 0; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return 1; } @@ -90,7 +90,7 @@ int bidib_get_protocol_version(const char *board) { return 1; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { unsigned int action_id = bidib_get_and_incr_action_id(); @@ -100,11 +100,11 @@ int bidib_get_protocol_version(const char *board) { tmp_board->node_addr.top, tmp_board->node_addr.sub, tmp_board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = tmp_board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_sys_get_p_version(tmp_addr, action_id); return 0; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return 1; } @@ -114,7 +114,7 @@ int bidib_get_software_version(const char *board) { return 1; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const tmp_board = bidib_state_get_board_ref(board); if (tmp_board != NULL && tmp_board->connected) { unsigned int action_id = bidib_get_and_incr_action_id(); @@ -124,10 +124,10 @@ int bidib_get_software_version(const char *board) { tmp_board->node_addr.top, tmp_board->node_addr.sub, tmp_board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = tmp_board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_sys_get_sw_version(tmp_addr, action_id); return 0; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return 1; } diff --git a/src/highlevel/bidib_highlevel_getter.c b/src/highlevel/bidib_highlevel_getter.c index a1823bb..2e7404f 100644 --- a/src/highlevel/bidib_highlevel_getter.c +++ b/src/highlevel/bidib_highlevel_getter.c @@ -248,7 +248,7 @@ t_bidib_track_state bidib_get_state(void) { t_bidib_id_list_query bidib_get_boards(void) { t_bidib_id_list_query query = {0, NULL}; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); if (bidib_boards->len > 0) { query.length = bidib_boards->len; query.ids = malloc(sizeof(char *) * query.length); @@ -257,14 +257,14 @@ t_bidib_id_list_query bidib_get_boards(void) { query.ids[i] = strdup(board_i->id->str); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_boards_connected(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const count_tmp = &g_array_index(bidib_boards, t_bidib_board, i); if (count_tmp != NULL && count_tmp->connected) { @@ -283,7 +283,7 @@ t_bidib_id_list_query bidib_get_boards_connected(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -293,12 +293,12 @@ bool bidib_get_board_connected(const char *board) { } bool res = false; // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const tmp = bidib_state_get_board_ref(board); if (tmp != NULL) { res = tmp->connected; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return res; } @@ -308,20 +308,20 @@ t_bidib_board_features_query bidib_get_board_features(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const tmp = bidib_state_get_board_ref(board); if (tmp != NULL && tmp->features->len != 0) { query.length = tmp->features->len; query.features = malloc(sizeof(char) * query.length * 2); memcpy(query.features, tmp->features->data, sizeof(t_bidib_board_feature) * query.length); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_query bidib_get_board_id(t_bidib_unique_id_mod unique_id) { t_bidib_id_query query = {false, NULL}; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); if (board_i != NULL && bidib_state_uids_equal(&unique_id, &board_i->unique_id)) { @@ -330,7 +330,7 @@ t_bidib_id_query bidib_get_board_id(t_bidib_unique_id_mod unique_id) { break; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -341,13 +341,13 @@ t_bidib_unique_id_query bidib_get_uniqueid(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && board_ref->unique_id.class_id != 0xFF) { query.known = true; query.unique_id = board_ref->unique_id; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -355,13 +355,13 @@ t_bidib_unique_id_query bidib_get_uniqueid_by_nodeaddr(t_bidib_node_address node t_bidib_unique_id_query query; query.known = false; // For bidib_state_get_board_ref_by_nodeaddr - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref_by_nodeaddr(node_address); if (board_ref != NULL && board_ref->connected) { query.known = true; query.unique_id = board_ref->unique_id; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -372,20 +372,20 @@ t_bidib_node_address_query bidib_get_nodeaddr(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && board_ref->connected) { query.known_and_connected = true; query.address = board_ref->node_addr; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_node_address_query bidib_get_nodeaddr_by_uniqueid(t_bidib_unique_id_mod uid) { t_bidib_node_address_query query; query.known_and_connected = false; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); if (board_i != NULL && bidib_state_uids_equal(&uid, &board_i->unique_id)) { @@ -394,7 +394,7 @@ t_bidib_node_address_query bidib_get_nodeaddr_by_uniqueid(t_bidib_unique_id_mod break; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -404,7 +404,7 @@ t_bidib_id_list_query bidib_get_board_points(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->points_board->len > 0 || board_ref->points_dcc->len > 0)) { @@ -426,7 +426,7 @@ t_bidib_id_list_query bidib_get_board_points(const char *board) { current_index++; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -436,7 +436,7 @@ t_bidib_id_list_query bidib_get_board_signals(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->signals_board->len > 0 || board_ref->signals_dcc->len > 0)) { @@ -458,7 +458,7 @@ t_bidib_id_list_query bidib_get_board_signals(const char *board) { current_index++; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -468,7 +468,7 @@ t_bidib_id_list_query bidib_get_board_peripherals(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->peripherals->len > 0)) { query.length = board_ref->peripherals->len; @@ -480,7 +480,7 @@ t_bidib_id_list_query bidib_get_board_peripherals(const char *board) { query.ids[i] = strdup(peripheral_mapping->id->str); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -490,7 +490,7 @@ t_bidib_id_list_query bidib_get_board_segments(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->segments->len > 0)) { query.length = board_ref->segments->len; @@ -502,7 +502,7 @@ t_bidib_id_list_query bidib_get_board_segments(const char *board) { query.ids[i] = strdup(segment_mapping->id->str); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -512,7 +512,7 @@ t_bidib_id_list_query bidib_get_board_reversers(const char *board) { return query; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board_ref = bidib_state_get_board_ref(board); if (board_ref != NULL && (board_ref->reversers->len > 0)) { query.length = board_ref->reversers->len; @@ -524,14 +524,14 @@ t_bidib_id_list_query bidib_get_board_reversers(const char *board) { query.ids[i] = strdup(reverser_mapping->id->str); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_connected_points(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref != NULL && board_ref->connected) { @@ -561,14 +561,14 @@ t_bidib_id_list_query bidib_get_connected_points(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_connected_signals(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref != NULL && board_ref->connected) { @@ -598,14 +598,14 @@ t_bidib_id_list_query bidib_get_connected_signals(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_connected_peripherals(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref != NULL && board_ref->connected) { @@ -628,14 +628,14 @@ t_bidib_id_list_query bidib_get_connected_peripherals(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_connected_segments(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref != NULL && board_ref->connected) { @@ -658,14 +658,14 @@ t_bidib_id_list_query bidib_get_connected_segments(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_connected_reversers(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref != NULL && board_ref->connected) { @@ -688,14 +688,14 @@ t_bidib_id_list_query bidib_get_connected_reversers(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } t_bidib_id_list_query bidib_get_connected_boosters(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref->connected && board_ref->unique_id.class_id & (1 << 1)) { @@ -714,7 +714,7 @@ t_bidib_id_list_query bidib_get_connected_boosters(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -738,7 +738,7 @@ t_bidib_id_list_query bidib_get_boosters(void) { t_bidib_id_list_query bidib_get_connected_track_outputs(void) { t_bidib_id_list_query query = {0, NULL}; size_t count = 0; - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_ref = &g_array_index(bidib_boards, t_bidib_board, i); if (board_ref != NULL && board_ref->connected && board_ref->unique_id.class_id & (1 << 4)) { @@ -758,7 +758,7 @@ t_bidib_id_list_query bidib_get_connected_track_outputs(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -1043,7 +1043,7 @@ t_bidib_track_output_state_query bidib_get_track_output_state(const char *track_ t_bidib_id_list_query bidib_get_trains(void) { t_bidib_id_list_query query = {0, NULL}; // For accessing bidib_trains - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); if (bidib_trains->len > 0) { query.length = bidib_trains->len; query.ids = malloc(sizeof(char *) * query.length); @@ -1052,7 +1052,7 @@ t_bidib_id_list_query bidib_get_trains(void) { query.ids[i] = strdup(train_i->id->str); } } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return query; } @@ -1089,7 +1089,7 @@ t_bidib_id_list_query bidib_get_trains_on_track(void) { t_bidib_id_query bidib_get_train_id(t_bidib_dcc_address dcc_address) { t_bidib_id_query query = {false, NULL}; // For accessing bidib_trains - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); for (size_t i = 0; i < bidib_trains->len; i++) { const t_bidib_train *const train_i = &g_array_index(bidib_trains, t_bidib_train, i); if (train_i->dcc_addr.addrl == dcc_address.addrl && @@ -1099,7 +1099,7 @@ t_bidib_id_query bidib_get_train_id(t_bidib_dcc_address dcc_address) { break; } } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return query; } @@ -1110,7 +1110,7 @@ t_bidib_dcc_address_query bidib_get_train_dcc_addr(const char *train) { return query; } // For bidib_state_get_train_ref - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); const t_bidib_train *const tmp = bidib_state_get_train_ref(train); if (tmp != NULL) { query.known = true; @@ -1118,7 +1118,7 @@ t_bidib_dcc_address_query bidib_get_train_dcc_addr(const char *train) { query.dcc_address.addrl = tmp->dcc_addr.addrl; query.dcc_address.type = tmp->dcc_addr.type; } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return query; } @@ -1128,7 +1128,7 @@ t_bidib_id_list_query bidib_get_train_peripherals(const char *train) { return query; } // For bidib_state_get_train_ref - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); const t_bidib_train *const tmp = bidib_state_get_train_ref(train); if (tmp != NULL) { query.length = tmp->peripherals->len; @@ -1139,7 +1139,7 @@ t_bidib_id_list_query bidib_get_train_peripherals(const char *train) { query.ids[i] = strdup(mapping_i->id->str); } } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return query; } @@ -1226,7 +1226,7 @@ t_bidib_train_position_query bidib_get_train_position_intern(const char *train) // Notes regarding mutexes/locks: // - bidib_state_get_train_state_ref: trackstate_trains_mutex // - access bidib_track_state.segments: trackstate_segments_mutex - // - bidib_state_get_train_ref: bidib_state_trains_rwlock >= read + // - bidib_state_get_train_ref: bidib_trains_rwlock >= read const t_bidib_train_state_intern *const train_state_ref = bidib_state_get_train_state_ref(train); const t_bidib_train *const train_ref = bidib_state_get_train_ref(train); @@ -1269,7 +1269,7 @@ t_bidib_train_position_query bidib_get_train_position_intern(const char *train) t_bidib_train_position_query bidib_get_train_position(const char *train) { // All for bidib_get_train_position_intern - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); pthread_mutex_lock(&trackstate_segments_mutex); pthread_mutex_lock(&trackstate_trains_mutex); @@ -1277,7 +1277,7 @@ t_bidib_train_position_query bidib_get_train_position(const char *train) { pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return query; } @@ -1321,14 +1321,14 @@ static t_bidib_id_list_query bidib_get_accessory_aspects(const char *accessory, return query; } // For bidib_state_get_board_accessory_mapping_ref, bidib_state_get_dcc_accessory_mapping_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board_accessory_mapping *const board_mapping = bidib_state_get_board_accessory_mapping_ref(accessory, point); if (board_mapping == NULL) { const t_bidib_dcc_accessory_mapping *const dcc_mapping = bidib_state_get_dcc_accessory_mapping_ref(accessory, point); if (dcc_mapping == NULL) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } else { query.length = dcc_mapping->aspects->len; @@ -1348,7 +1348,7 @@ static t_bidib_id_list_query bidib_get_accessory_aspects(const char *accessory, query.ids[i] = strdup(aspect_mapping->id->str); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } @@ -1366,7 +1366,7 @@ t_bidib_id_list_query bidib_get_peripheral_aspects(const char *peripheral) { return query; } // For bidib_state_get_peripheral_mapping_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_peripheral_mapping *const peripheral_mapping = bidib_state_get_peripheral_mapping_ref(peripheral); if (peripheral_mapping != NULL) { @@ -1378,7 +1378,7 @@ t_bidib_id_list_query bidib_get_peripheral_aspects(const char *peripheral) { query.ids[i] = strdup(aspect_mapping->id->str); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return query; } diff --git a/src/highlevel/bidib_highlevel_intern.h b/src/highlevel/bidib_highlevel_intern.h index 6893231..65c4ccc 100644 --- a/src/highlevel/bidib_highlevel_intern.h +++ b/src/highlevel/bidib_highlevel_intern.h @@ -35,8 +35,8 @@ #include "../../include/definitions/bidib_definitions_custom.h" -extern pthread_rwlock_t bidib_state_trains_rwlock; -extern pthread_rwlock_t bidib_state_boards_rwlock; +extern pthread_rwlock_t bidib_trains_rwlock; +extern pthread_rwlock_t bidib_boards_rwlock; extern pthread_mutex_t bidib_action_id_mutex; extern pthread_mutex_t trackstate_accessories_mutex; @@ -58,7 +58,7 @@ unsigned int bidib_get_and_incr_action_id(void); * Used only internally in bidib_state_update_train_available and * bidib_get_train_position to avoid the usage of a recursive mutex. * - * Shall only be called with with bidib_state_trains_rwlock >= read acquired, + * Shall only be called with with bidib_trains_rwlock >= read acquired, * and with trackstate_segments_mutex and trackstate_trains_mutex acquired. * * @param train the id of the train. diff --git a/src/highlevel/bidib_highlevel_setter.c b/src/highlevel/bidib_highlevel_setter.c index e48bc56..d08d472 100644 --- a/src/highlevel/bidib_highlevel_setter.c +++ b/src/highlevel/bidib_highlevel_setter.c @@ -75,7 +75,7 @@ int bidib_switch_point(const char *point, const char *aspect) { pthread_mutex_lock(&trackstate_accessories_mutex); // For accessing bidib_boards and bidib_send_cs_accessory_intern - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { @@ -89,7 +89,7 @@ int bidib_switch_point(const char *point, const char *aspect) { if (!board_i->connected) { syslog_libbidib(LOG_ERR, "Switch point %s: board %s is not connected", point, board_i->id->str); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -112,7 +112,7 @@ int bidib_switch_point(const char *point, const char *aspect) { point, aspect); ret = 1; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } @@ -126,7 +126,7 @@ int bidib_switch_point(const char *point, const char *aspect) { if (!board_i->connected) { syslog_libbidib(LOG_ERR, "Switch point %s: board %s is not connected", point, board_i->id->str); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -171,11 +171,11 @@ int bidib_switch_point(const char *point, const char *aspect) { tmp_addr.subsub, aspect, action_id); ret = 1; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } else { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Switch point %s: aspect %s doesn't exist", point, aspect); @@ -184,7 +184,7 @@ int bidib_switch_point(const char *point, const char *aspect) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Switch point %s: not found", point); return 1; @@ -200,7 +200,7 @@ int bidib_set_signal(const char *signal, const char *aspect) { pthread_mutex_lock(&trackstate_accessories_mutex); // For accessing bidib_boards and bidib_send_cs_accessory_intern - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); @@ -211,7 +211,7 @@ int bidib_set_signal(const char *signal, const char *aspect) { if (!board_i->connected) { syslog_libbidib(LOG_ERR, "Set signal %s: board %s is not connected", signal, board_i->id->str); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -233,7 +233,7 @@ int bidib_set_signal(const char *signal, const char *aspect) { signal, aspect); ret = 1; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } @@ -246,7 +246,7 @@ int bidib_set_signal(const char *signal, const char *aspect) { if (!board_i->connected) { syslog_libbidib(LOG_ERR, "Set signal %s: board %s is not connected", signal, board_i->id->str); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return 1; } @@ -293,13 +293,13 @@ int bidib_set_signal(const char *signal, const char *aspect) { signal, aspect); ret = 1; } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); return ret; } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); syslog_libbidib(LOG_ERR, "Set signal %s: not found", signal); return 1; @@ -311,7 +311,7 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { return 1; } // For accessing bidib_boards - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); for (size_t j = 0; j < board_i->peripherals->len; j++) { @@ -321,7 +321,7 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { if (!board_i->connected) { syslog_libbidib(LOG_ERR, "Set peripheral %s: board %s is not connected", peripheral, board_i->id->str); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return 1; } const t_bidib_aspect *const aspect_mapping = @@ -335,10 +335,10 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { aspect_mapping->id->str, aspect_mapping->value, action_id); bidib_send_lc_output(board_i->node_addr, peripheral_mapping->port.port0, peripheral_mapping->port.port1, aspect_mapping->value, action_id); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return 0; } else { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); syslog_libbidib(LOG_ERR, "Set peripheral %s: aspect %s doesn't exist", peripheral, aspect); return 1; @@ -346,14 +346,14 @@ int bidib_set_peripheral(const char *peripheral, const char *aspect) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); syslog_libbidib(LOG_ERR, "Set peripheral %s: not found", peripheral); return 1; } /** * Set the train speed on track output to some value. - * Shall only be called with bidib_state_trains_rwlock >=read acquired. + * Shall only be called with bidib_trains_rwlock >=read acquired. * * @param train the id/name of the train whose speed to set * @param speed the speed to set @@ -372,32 +372,32 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra return 1; } // Notes regarding mutexes/locks: - // - bidib_state_get_train_ref: bidib_state_trains_rwlock >=read -> by caller - // - bidib_state_get_board_ref: bidib_state_boards_rwlock >=read -> locked locally + // - bidib_state_get_train_ref: bidib_trains_rwlock >=read -> by caller + // - bidib_state_get_board_ref: bidib_boards_rwlock >=read -> locked locally // - bidib_state_get_train_state_ref: trackstate_trains_mutex -> locked locally - // - bidib_send_cs_drive_intern: we pass false -> need lock bidib_state_trains_rwlock -> caller - // Important: trackstate_trains_mutex and bidib_state_boards_rwlock have to be released + // - bidib_send_cs_drive_intern: we pass false -> need lock bidib_trains_rwlock -> caller + // Important: trackstate_trains_mutex and bidib_boards_rwlock have to be released // before bidib_send_cs_drive_intern is called. const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); // For bidib_state_get_train_state_ref pthread_mutex_lock(&trackstate_trains_mutex); // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (tmp_train == NULL) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); syslog_libbidib(LOG_ERR, "Set train speed: train %s doesn't exist", train); return 1; } else if (board == NULL || !board->connected) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); syslog_libbidib(LOG_ERR, "Set train speed: board %s doesn't exist or is not connected", track_output); return 1; } else if (!(board->unique_id.class_id & (1 << 4))) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); syslog_libbidib(LOG_ERR, "Set train speed: board %s has no track output", track_output); @@ -437,7 +437,7 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra train, speed, board->id->str, board->node_addr.top, board->node_addr.sub, board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); return 0; @@ -447,9 +447,9 @@ int bidib_set_train_speed_internal(const char *train, int speed, const char *tra int bidib_set_train_speed(const char *train, int speed, const char *track_output) { int ret = 0; // For bidib_set_train_speed_internal - pthread_rwlock_wrlock(&bidib_state_trains_rwlock); + pthread_rwlock_wrlock(&bidib_trains_rwlock); ret = bidib_set_train_speed_internal(train, speed, track_output); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return ret; } @@ -463,10 +463,10 @@ int bidib_set_calibrated_train_speed(const char *train, int speed, const char *t return 1; } // For bidib_state_get_train_ref and bidib_set_train_speed_internal - pthread_rwlock_wrlock(&bidib_state_trains_rwlock); + pthread_rwlock_wrlock(&bidib_trains_rwlock); const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); if (tmp_train == NULL) { - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); syslog_libbidib(LOG_ERR, "Set calibrated train speed: %s train does not exist", train); return 1; } @@ -474,7 +474,7 @@ int bidib_set_calibrated_train_speed(const char *train, int speed, const char *t if (tmp_train->calibration == NULL) { syslog_libbidib(LOG_ERR, "Set calibrated train speed: no calibration for train %s", tmp_train->id->str); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return 1; } @@ -490,7 +490,7 @@ int bidib_set_calibrated_train_speed(const char *train, int speed, const char *t train, g_array_index(tmp_train->calibration, int, speed - 1), track_output); } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return error; } @@ -500,26 +500,26 @@ int bidib_emergency_stop_train(const char *train, const char *track_output) { return 1; } // For bidib_state_get_train_ref - pthread_rwlock_wrlock(&bidib_state_trains_rwlock); + pthread_rwlock_wrlock(&bidib_trains_rwlock); // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (tmp_train == NULL) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); syslog_libbidib(LOG_ERR, "Emergency stop train: train %s doesn't exist", train); return 1; } else if (board == NULL || !board->connected) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); syslog_libbidib(LOG_ERR, "Emergency stop train: board %s doesn't exist or is not connected", track_output); return 1; } else if (!(board->unique_id.class_id & (1 << 4))) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); syslog_libbidib(LOG_ERR, "Emergency stop train: board %s is no track output", track_output); return 1; @@ -550,16 +550,16 @@ int bidib_emergency_stop_train(const char *train, const char *track_output) { train, board->id->str, board->node_addr.top, board->node_addr.sub, board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return 0; } } /** * Get the current bit(s) for the train peripherals. - * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * Shall only be called with bidib_trains_rwlock >= read acquired, * and with trackstate_trains_mutex acquired. * * @param train @@ -589,18 +589,18 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ return 1; } // Notes on mutexes/locks: - // - bidib_state_get_train_ref: bidib_state_trains_rwlock >=read - // - bidib_state_get_board_ref: bidib_state_boards_rwlock >=read + // - bidib_state_get_train_ref: bidib_trains_rwlock >=read + // - bidib_state_get_board_ref: bidib_boards_rwlock >=read // - bidib_get_current_train_peripheral_bits: trackstate_trains_mutex (and techn. trains_wrlock) - // - bidib_send_cs_drive_intern: bidib_state_trains_rwlock >=read (as we pass false for lock param) + // - bidib_send_cs_drive_intern: bidib_trains_rwlock >=read (as we pass false for lock param) // For bidib_state_get_train_ref and bidib_send_cs_drive_intern - pthread_rwlock_wrlock(&bidib_state_trains_rwlock); + pthread_rwlock_wrlock(&bidib_trains_rwlock); // For bidib_get_current_train_peripheral_bits pthread_mutex_lock(&trackstate_trains_mutex); // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_train *const tmp_train = bidib_state_get_train_ref(train); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); @@ -616,9 +616,9 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ syslog_libbidib(LOG_ERR, "Set train peripheral: board %s is not a track output", track_output); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return 1; } @@ -676,16 +676,16 @@ int bidib_set_train_peripheral(const char *train, const char *peripheral, uint8_ peripheral, train, state, board->id->str, board->node_addr.top, board->node_addr.sub, board->node_addr.subsub, action_id); t_bidib_node_address tmp_addr = board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); bidib_send_cs_drive_intern(tmp_addr, params, action_id, false); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); return 0; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_trains_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); syslog_libbidib(LOG_ERR, "Set train peripheral: peripheral %s doesn't exist", peripheral); return 1; } @@ -696,15 +696,15 @@ int bidib_set_booster_power_state(const char *booster, bool on) { return 1; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref(booster); if (board == NULL || !board->connected) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); syslog_libbidib(LOG_ERR, "Set booster: board %s doesn't exist or is not connected", booster); return 1; } else if (!(board->unique_id.class_id & (1 << 1))) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); syslog_libbidib(LOG_ERR, "Set booster: board %s is no booster", booster); return 1; } else { @@ -715,7 +715,7 @@ int bidib_set_booster_power_state(const char *booster, bool on) { board->id->str, board->node_addr.top, board->node_addr.sub, board->node_addr.subsub, "on", action_id); t_bidib_node_address tmp_addr = board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_boost_on(tmp_addr, 0x01, action_id); } else { syslog_libbidib(LOG_NOTICE, "Set booster: %s (0x%02x 0x%02x " @@ -723,7 +723,7 @@ int bidib_set_booster_power_state(const char *booster, bool on) { board->id->str, board->node_addr.top, board->node_addr.sub, board->node_addr.subsub, "off", action_id); t_bidib_node_address tmp_addr = board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_boost_off(tmp_addr, 0x01, action_id); } return 0; @@ -736,16 +736,16 @@ int bidib_set_track_output_state(const char *track_output, t_bidib_cs_state stat return 1; } // For bidib_state_get_board_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref(track_output); if (board == NULL || !board->connected) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); syslog_libbidib(LOG_ERR, "Set track output state: board %s does not exist or is not connected", track_output); return 1; } else if (!(board->unique_id.class_id & (1 << 4))) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); syslog_libbidib(LOG_ERR, "Set track output state: board %s is no track output", track_output); return 1; @@ -756,14 +756,14 @@ int bidib_set_track_output_state(const char *track_output, t_bidib_cs_state stat board->id->str, board->node_addr.top, board->node_addr.sub, board->node_addr.subsub, state, action_id); t_bidib_node_address tmp_addr = board->node_addr; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_cs_set_state(tmp_addr, state, action_id); return 0; } } void bidib_set_track_output_state_all(t_bidib_cs_state state) { - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); unsigned int action_id = bidib_get_and_incr_action_id(); syslog_libbidib(LOG_NOTICE, "Set all track outputs to state: 0x%02x with action id: %d", state, action_id); @@ -773,7 +773,7 @@ void bidib_set_track_output_state_all(t_bidib_cs_state state) { bidib_send_cs_set_state(board_i->node_addr, state, action_id); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); } int bidib_request_reverser_state(const char *reverser, const char *board) { @@ -785,20 +785,20 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { // For bidib_state_get_reverser_state_ref (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); // For bidib_state_get_board_ref and bidib_state_get_reverser_mapping_ref - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *board_ref = bidib_state_get_board_ref(board); const t_bidib_reverser_mapping *mapping_ref = bidib_state_get_reverser_mapping_ref(reverser); t_bidib_reverser_state *state_ref = bidib_state_get_reverser_state_ref(reverser); if (board_ref == NULL || !board_ref->connected) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Request reverser state: board %s doesn't exist or is not connected", board); return 1; } else if (mapping_ref == NULL || state_ref == NULL) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Request reverser state: reverser %s does not exist", @@ -814,7 +814,7 @@ int bidib_request_reverser_state(const char *reverser, const char *board) { bidib_send_vendor_get(board_ref->node_addr, (uint8_t)mapping_ref->cv->len, (uint8_t *)mapping_ref->cv->str, 0); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); return 0; } diff --git a/src/highlevel/bidib_highlevel_util.c b/src/highlevel/bidib_highlevel_util.c index acc8789..71430ab 100644 --- a/src/highlevel/bidib_highlevel_util.c +++ b/src/highlevel/bidib_highlevel_util.c @@ -52,8 +52,8 @@ static pthread_t bidib_heartbeat_thread = 0; // bidib_track_state, bidib_trains data structures. // They do NOT protect the concurrent sending of low-level commands // to the BiDiB master node over a serial connection. -pthread_rwlock_t bidib_state_trains_rwlock; -pthread_rwlock_t bidib_state_boards_rwlock; +pthread_rwlock_t bidib_trains_rwlock; +pthread_rwlock_t bidib_boards_rwlock; pthread_mutex_t trackstate_accessories_mutex; pthread_mutex_t trackstate_peripherals_mutex; @@ -69,8 +69,8 @@ volatile bool bidib_discard_rx = true; volatile bool bidib_lowlevel_debug_mode = false; static void bidib_init_rwlocks(void) { - pthread_rwlock_init(&bidib_state_trains_rwlock, NULL); - pthread_rwlock_init(&bidib_state_boards_rwlock, NULL); + pthread_rwlock_init(&bidib_trains_rwlock, NULL); + pthread_rwlock_init(&bidib_boards_rwlock, NULL); } static void bidib_init_mutexes(void) { diff --git a/src/lowlevel/bidib_lowlevel_intern.h b/src/lowlevel/bidib_lowlevel_intern.h index 5f76f67..e92d8cc 100644 --- a/src/lowlevel/bidib_lowlevel_intern.h +++ b/src/lowlevel/bidib_lowlevel_intern.h @@ -36,7 +36,7 @@ /** * Used to avoid the usage of a recursive rwlock. - * Shall be called with param `lock` = false if bidib_state_trains_rwlock + * Shall be called with param `lock` = false if bidib_trains_rwlock * has already been acquired with >= read. * * @param node_address the three bytes on top of the address stack. @@ -52,7 +52,7 @@ void bidib_send_cs_drive_intern(t_bidib_node_address node_address, /** * Issues an accessory command. * Shall only be called with trackstate_accessories_mutex acquired, - * and with bidib_state_boards_rwlock >=read acquired. + * and with bidib_boards_rwlock >=read acquired. * * @param node_address the three bytes on top of the address stack. * @param cs_accessory_params the parameters. diff --git a/src/lowlevel/bidib_lowlevel_system.c b/src/lowlevel/bidib_lowlevel_system.c index f77003b..e1fd05c 100644 --- a/src/lowlevel/bidib_lowlevel_system.c +++ b/src/lowlevel/bidib_lowlevel_system.c @@ -123,9 +123,9 @@ void bidib_send_sys_reset(unsigned int action_id) { bidib_set_track_output_state_all(BIDIB_CS_GO); bidib_flush(); usleep(500000); // wait for track output so it can receive initial values - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_state_query_occupancy(); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_flush(); usleep(500000); // wait for occupancy data bidib_state_set_initial_values(); diff --git a/src/lowlevel/bidib_lowlevel_track.c b/src/lowlevel/bidib_lowlevel_track.c index f76e99c..8901a32 100644 --- a/src/lowlevel/bidib_lowlevel_track.c +++ b/src/lowlevel/bidib_lowlevel_track.c @@ -83,9 +83,9 @@ void bidib_send_cs_drive_intern(t_bidib_node_address node_address, cs_drive_params.function3, cs_drive_params.function4}; bidib_buffer_message_with_data(addr_stack, MSG_CS_DRIVE, 9, data, action_id); if (lock) { - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); bidib_state_cs_drive(cs_drive_params); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } else { bidib_state_cs_drive(cs_drive_params); } @@ -114,11 +114,11 @@ void bidib_send_cs_accessory(t_bidib_node_address node_address, unsigned int action_id) { // Both for bidib_send_cs_accessory_intern (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_send_cs_accessory_intern(node_address, cs_accessory_params, action_id); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); } diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index 1a1d474..d355cc5 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -94,7 +94,7 @@ int bidib_state_init(const char *config_dir) { // Locks/Mutexes: // - Writes to bidib_boards array is protected by acquiring -// bidib_state_boards_rwlock. +// bidib_boards_rwlock. // - Internal: bidib_uplink_intern_queue_mutex, bidib_node_state_table_mutex // Params: // - May modify sub_iface_queue: Appends interface nodes. @@ -173,7 +173,7 @@ static bool bidib_state_query_nodetab(t_bidib_node_address node_address, } else { node_address_i.subsub = local_node_addr; } - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); t_bidib_board *board_i = bidib_state_get_board_ref_by_uniqueid(unique_id_i); if (board_i == NULL) { syslog_libbidib(LOG_ERR, @@ -188,7 +188,7 @@ static bool bidib_state_query_nodetab(t_bidib_node_address node_address, board_i->id->str, board_i->node_addr.top, board_i->node_addr.sub, board_i->node_addr.subsub); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); if (i > 0 && unique_id_i.class_id & (1 << 7)) { // add node to queue if it is an interface t_bidib_node_address *sub_iface_addr = malloc(sizeof(t_bidib_node_address)); @@ -248,7 +248,7 @@ void bidib_state_query_occupancy(void) { } void bidib_state_set_board_features(void) { - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); if (board_i->connected) { @@ -298,7 +298,7 @@ void bidib_state_set_board_features(void) { } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); } void bidib_state_set_initial_values(void) { @@ -415,19 +415,19 @@ t_bidib_bm_confidence_level bidib_bm_confidence_to_level(t_bidib_segment_state_c bool bidib_state_add_board(t_bidib_board board) { bool error = false; // For bidib_state_get_board_ref, bidib_state_get_board_ref_by_uniqueid, and accessing bidib_boards - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); if (bidib_state_get_board_ref(board.id->str) != NULL || bidib_state_get_board_ref_by_uniqueid(board.unique_id) != NULL) { error = true; } else { g_array_append_val(bidib_boards, board); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return error; } bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address) { - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_boards->len; i++) { const t_bidib_board *const tmp_board = &g_array_index(bidib_boards, t_bidib_board, i); @@ -437,7 +437,7 @@ bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address) { t_bidib_dcc_accessory_mapping, j); if (tmp_dcc_mapping->dcc_addr.addrl == dcc_address.addrl && tmp_dcc_mapping->dcc_addr.addrh == dcc_address.addrh) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return true; } } @@ -448,12 +448,12 @@ bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address) { t_bidib_dcc_accessory_mapping, j); if (tmp_dcc_mapping->dcc_addr.addrl == dcc_address.addrl && tmp_dcc_mapping->dcc_addr.addrh == dcc_address.addrh) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return true; } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); for (size_t i = 0; i < bidib_trains->len; i++) { const t_bidib_train *const tmp_train = &g_array_index(bidib_trains, t_bidib_train, i); @@ -611,12 +611,12 @@ bool bidib_state_add_board_signal_state(t_bidib_board_accessory_state signal_sta bool bidib_state_add_dcc_point_state(t_bidib_dcc_accessory_state point_state, t_bidib_dcc_address dcc_address) { - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); if (bidib_state_point_exists(point_state.id) || bidib_state_dcc_addr_in_use(dcc_address)) { return true; } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); // For accessing bidib_track_state.points_dcc (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); @@ -627,12 +627,12 @@ bool bidib_state_add_dcc_point_state(t_bidib_dcc_accessory_state point_state, bool bidib_state_add_dcc_signal_state(t_bidib_dcc_accessory_state signal_state, t_bidib_dcc_address dcc_address) { - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); if (bidib_state_signal_exists(signal_state.id) || bidib_state_dcc_addr_in_use(dcc_address)) { return true; } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); // For accessing bidib_track_state.signals_dcc (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); @@ -694,7 +694,7 @@ void bidib_state_update_train_available(void) { // Notes regarding mutexes/locks: // - accessing bidib_track_state.trains: trackstate_trains_mutex // - bidib_get_train_position_intern: - // trackstate_segments_mutex, trackstate_trains_mutex, bidib_state_trains_rwlock >= read + // trackstate_segments_mutex, trackstate_trains_mutex, bidib_trains_rwlock >= read t_bidib_train_state_intern *train_state; t_bidib_train_position_query query; struct timespec tv; @@ -877,7 +877,7 @@ void bidib_state_reset_train_params(void) { params.function3 = 0x00; params.function4 = 0x00; // For bidib_send_cs_drive_intern - pthread_rwlock_wrlock(&bidib_state_trains_rwlock); + pthread_rwlock_wrlock(&bidib_trains_rwlock); for (size_t i = 0; i < bidib_trains->len; i++) { const t_bidib_train *const train_i = &g_array_index(bidib_trains, t_bidib_train, i); params.dcc_address = train_i->dcc_addr; @@ -894,16 +894,16 @@ void bidib_state_reset_train_params(void) { break; } // For accessing bidib_boards - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); for (size_t j = 0; j < bidib_boards->len; j++) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, j); if (board_i->connected && board_i->unique_id.class_id & (1 << 4)) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_send_cs_drive_intern(board_i->node_addr, params, 0, false); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); } - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } diff --git a/src/state/bidib_state_getter.c b/src/state/bidib_state_getter.c index 72a58ac..36bd33f 100644 --- a/src/state/bidib_state_getter.c +++ b/src/state/bidib_state_getter.c @@ -322,7 +322,7 @@ t_bidib_segment_state_intern bidib_state_get_segment_state( t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( t_bidib_node_address node_address, uint8_t number) { // For bidib_state_get_board_ref_by_nodeaddr - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref_by_nodeaddr(node_address); if (board != NULL) { for (size_t i = 0; i < board->segments->len; i++) { @@ -330,12 +330,12 @@ t_bidib_segment_state_intern *bidib_state_get_segment_state_ref_by_nodeaddr( t_bidib_segment_mapping, i); if (mapping_i.addr == number) { t_bidib_segment_state_intern *ret = bidib_state_get_segment_state_ref(mapping_i.id->str); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return ret; } } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return NULL; } @@ -452,12 +452,12 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( t_bidib_node_address node_address) { t_bidib_booster_state *booster_state = NULL; // For bidib_state_get_board_ref_by_nodeaddr - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); if (sender != NULL) { booster_state = bidib_state_get_booster_state_ref(sender->id->str); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return booster_state; } @@ -465,11 +465,11 @@ t_bidib_track_output_state *bidib_state_get_track_output_state_ref_by_nodeaddr( t_bidib_node_address node_address) { t_bidib_track_output_state *track_output_state = NULL; // For bidib_state_get_board_ref_by_nodeaddr - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *sender = bidib_state_get_board_ref_by_nodeaddr(node_address); if (sender != NULL) { track_output_state = bidib_state_get_track_output_state_ref(sender->id->str); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return track_output_state; } diff --git a/src/state/bidib_state_getter_intern.h b/src/state/bidib_state_getter_intern.h index 48010bc..c4821d9 100644 --- a/src/state/bidib_state_getter_intern.h +++ b/src/state/bidib_state_getter_intern.h @@ -37,7 +37,7 @@ /** * Returns the reference to the board with the given id. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param board the id of the board. * @return NULL if not found, otherwise the reference to the board. @@ -46,7 +46,7 @@ t_bidib_board *bidib_state_get_board_ref(const char *board); /** * Returns the reference to the board with the given unique id. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param unique_id the unique id of the board. * @return NULL if not found, otherwise the reference to the board. @@ -73,7 +73,7 @@ t_bidib_track_output_state *bidib_state_get_track_output_state_ref(const char *t /** * Returns the reference to the board accessory mapping with the given id. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param accessory the id of the board accessory. * @param point whether the accessory is a point or a signal. @@ -84,7 +84,7 @@ t_bidib_board_accessory_mapping *bidib_state_get_board_accessory_mapping_ref( /** * Returns the reference to the board accessory mapping with the given number. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param number the number of the accessory. @@ -108,7 +108,7 @@ t_bidib_board_accessory_state *bidib_state_get_board_accessory_state_ref(const c /** * Returns the reference to the dcc accessory mapping with the given id. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param accessory the id of the dcc accessory. * @param point whether the accessory is a point or a signal. @@ -119,7 +119,7 @@ t_bidib_dcc_accessory_mapping *bidib_state_get_dcc_accessory_mapping_ref( /** * Returns the reference to the dcc accessory mapping with the given dcc address. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -143,7 +143,7 @@ t_bidib_dcc_accessory_state *bidib_state_get_dcc_accessory_state_ref(const char /** * Returns the reference to the peripheral mapping with the given id. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param peripheral the id of the peripheral. * @return NULL if not found, otherwise the reference to the peripheral mapping. @@ -152,7 +152,7 @@ t_bidib_peripheral_mapping *bidib_state_get_peripheral_mapping_ref(const char *p /** * Returns the reference to the peripheral mapping with the given port. - * Shall only be called with the bidib_state_boards_rwlock >= read acquired. + * Shall only be called with the bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param port the port of the peripheral. @@ -191,8 +191,8 @@ t_bidib_segment_state_intern bidib_state_get_segment_state( /** * Returns the reference to the segment state with the given id. * Shall only be called with trackstate_segments_mutex acquired. - * Note: uses bidib_state_boards_rwlock internally, so shall not be called - * with bidib_state_boards_rwlock already acquired. + * Note: uses bidib_boards_rwlock internally, so shall not be called + * with bidib_boards_rwlock already acquired. * * @param node_address the node address of the board. * @param number the number on the board. @@ -212,7 +212,7 @@ t_bidib_reverser_state *bidib_state_get_reverser_state_ref(const char *reverser) /** * Returns the reference to the reverser mapping with the given CV. - * Shall only be called with the bidib_state_boards_rwlock >= read acquired. + * Shall only be called with the bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param cv the CV of the reverser. @@ -223,7 +223,7 @@ t_bidib_reverser_mapping *bidib_state_get_reverser_mapping_ref_by_cv( /** * Returns the reference to the reverser mapping with the given id. - * Shall only be called with the bidib_state_boards_rwlock >= read acquired. + * Shall only be called with the bidib_boards_rwlock >= read acquired. * * @param id the name of the reverser. * @return NULL if not found, otherwise the reference to the reverser mapping. @@ -232,7 +232,7 @@ t_bidib_reverser_mapping *bidib_state_get_reverser_mapping_ref(const char *rever /** * Returns the reference to the board with the given node address. - * Shall only be called with bidib_state_boards_rwlock >= read acquired. + * Shall only be called with bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the board. @@ -241,7 +241,7 @@ t_bidib_board *bidib_state_get_board_ref_by_nodeaddr(t_bidib_node_address node_a /** * Returns the reference to the train with the given id. - * Shall only be called with bidib_state_trains_rwlock >= read acquired. + * Shall only be called with bidib_trains_rwlock >= read acquired. * * @param train the id of the train. * @return NULL if not found, otherwise the reference to the train. @@ -250,7 +250,7 @@ t_bidib_train *bidib_state_get_train_ref(const char *train); /** * Returns the reference to the train state with the given dcc address. - * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * Shall only be called with bidib_trains_rwlock >= read acquired, * and with trackstate_trains_mutex acquired. * * @param dcc_address the dcc address of the train. @@ -261,7 +261,7 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref_by_dccaddr( /** * Returns the reference to the train peripheral state with the given bit. - * Shall only be called with bidib_state_trains_rwlock >= read acquired. + * Shall only be called with bidib_trains_rwlock >= read acquired. * * @param train_state the train state. * @param bit the bit of the peripheral. @@ -282,7 +282,7 @@ t_bidib_train_state_intern *bidib_state_get_train_state_ref(const char *train); /** * Returns the reference to the booster state with the given node address. * Shall only be called with trackstate_boosters_mutex acquired. - * Note: uses bidib_state_boards_rwlock internally. + * Note: uses bidib_boards_rwlock internally. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the booster state. @@ -293,7 +293,7 @@ t_bidib_booster_state *bidib_state_get_booster_state_ref_by_nodeaddr( /** * Returns the reference to the track output state with the given node address. * Shall only be called with trackstate_track_outputs_mutex acquired. - * Note: uses bidib_state_boards_rwlock internally. + * Note: uses bidib_boards_rwlock internally. * * @param node_address the node address of the board. * @return NULL if not found, otherwise the reference to the track output state. diff --git a/src/state/bidib_state_intern.h b/src/state/bidib_state_intern.h index b17aded..0b846a4 100644 --- a/src/state/bidib_state_intern.h +++ b/src/state/bidib_state_intern.h @@ -167,8 +167,8 @@ typedef struct { GArray *trains; } t_bidib_state_initial_values; -extern pthread_rwlock_t bidib_state_trains_rwlock; -extern pthread_rwlock_t bidib_state_boards_rwlock; +extern pthread_rwlock_t bidib_trains_rwlock; +extern pthread_rwlock_t bidib_boards_rwlock; extern pthread_mutex_t trackstate_accessories_mutex; extern pthread_mutex_t trackstate_peripherals_mutex; @@ -415,8 +415,8 @@ void bidib_state_free_single_segment_state_intern(t_bidib_segment_state_intern s /** * Checks whether a dcc address is already used by a train, point or signal. - * Shall only be called with bidib_state_trains_rwlock >=read acquired. - * Note: uses bidib_state_boards_rwlock internally. + * Shall only be called with bidib_trains_rwlock >=read acquired. + * Note: uses bidib_boards_rwlock internally. * * @param dcc_address the dcc address which should be checked. * @return true if the dcc address is already in use, otherwise false. @@ -425,7 +425,7 @@ bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address); /** * Adds a train to the current state. - * Shall only be called with bidib_state_trains_rwlock >= read acquired. + * Shall only be called with bidib_trains_rwlock >= read acquired. * * @param train the new train. * @return true if NULL or train already exists, otherwise false. @@ -469,7 +469,7 @@ void bidib_state_add_initial_train_value(t_bidib_state_train_initial_value value /** * Updates the available state for all trains. - * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * Shall only be called with bidib_trains_rwlock >= read acquired, * and with trackstate_segments_mutex and trackstate_trains_mutex acquired. */ void bidib_state_update_train_available(void); diff --git a/src/state/bidib_state_setter.c b/src/state/bidib_state_setter.c index b3875af..774ae2f 100644 --- a/src/state/bidib_state_setter.c +++ b/src/state/bidib_state_setter.c @@ -42,7 +42,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, // For bidib_state_get_reverser_state_ref (devnote: write) pthread_mutex_lock(&trackstate_reversers_mutex); // For bidib_state_get_reverser_mapping_ref_by_cv - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); uint8_t name_len = value_list[0]; char *name = strndup((const char *)&value_list[1], name_len); @@ -56,7 +56,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, t_bidib_reverser_state *reverser_state = bidib_state_get_reverser_state_ref(mapping->id->str); if (reverser_state == NULL) { - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); syslog_libbidib(LOG_ERR, "Feedback for vendor-specific configuration %s (value %s) " @@ -96,7 +96,7 @@ void bidib_state_vendor(t_bidib_node_address node_address, uint8_t length, node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_reversers_mutex); free(name); @@ -127,7 +127,7 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb // For bidib_state_get_board_accessory_state_ref (devnote: write) pthread_mutex_lock(&trackstate_accessories_mutex); // For bidib_state_get_board_accessory_mapping_ref_by_number - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bool point; const t_bidib_board_accessory_mapping *const accessory_mapping = bidib_state_get_board_accessory_mapping_ref_by_number(node_address, number, &point); @@ -184,14 +184,14 @@ void bidib_state_accessory_state(t_bidib_node_address node_address, uint8_t numb "No board accessory 0x%02x configured for node address 0x%02x 0x%02x 0x%02x 0x00", number, node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); } void bidib_state_node_new(t_bidib_node_address node_address, uint8_t local_addr, t_bidib_unique_id_mod unique_id) { // For bidib_state_get_board_ref_by_uniqueid - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); t_bidib_board *board = bidib_state_get_board_ref_by_uniqueid(unique_id); if (board != NULL) { board->connected = true; @@ -210,7 +210,7 @@ void bidib_state_node_new(t_bidib_node_address node_address, uint8_t local_addr, unique_id.product_id1, unique_id.product_id2, unique_id.product_id3, unique_id.product_id4); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); } static bool bidib_state_is_subnode(t_bidib_node_address node_address, @@ -232,7 +232,7 @@ static bool bidib_state_is_subnode(t_bidib_node_address node_address, void bidib_state_node_lost(t_bidib_unique_id_mod unique_id) { // For bidib_state_get_board_ref_by_uniqueid - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); t_bidib_board *board = bidib_state_get_board_ref_by_uniqueid(unique_id); if (board != NULL) { board->connected = false; @@ -253,7 +253,7 @@ void bidib_state_node_lost(t_bidib_unique_id_mod unique_id) { unique_id.product_id1, unique_id.product_id2, unique_id.product_id3, unique_id.product_id4); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); } void bidib_state_cs_state(t_bidib_node_address node_address, uint8_t state, @@ -279,7 +279,7 @@ void bidib_state_cs_state(t_bidib_node_address node_address, uint8_t state, void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, unsigned int action_id) { // For bidib_state_get_train_state_ref_by_dccaddr and bidib_state_dcc_addr_in_use - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); @@ -300,7 +300,7 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, unsi } } pthread_mutex_unlock(&trackstate_trains_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } void bidib_state_cs_accessory_ack(t_bidib_node_address node_address, @@ -474,7 +474,7 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p // For bidib_state_get_peripheral_state_ref (devnote: write) pthread_mutex_lock(&trackstate_peripherals_mutex); // For bidib_state_get_peripheral_mapping_ref_by_port - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_peripheral_mapping *const peripheral_mapping = bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); @@ -509,7 +509,7 @@ void bidib_state_lc_stat(t_bidib_node_address node_address, t_bidib_peripheral_p port.port0, port.port1, node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); } @@ -520,7 +520,7 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p // For bidib_state_get_peripheral_state_ref (devnote: write) pthread_mutex_lock(&trackstate_peripherals_mutex); // For bidib_state_get_peripheral_mapping_ref_by_port - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_peripheral_mapping *const peripheral_mapping = bidib_state_get_peripheral_mapping_ref_by_port(node_address, port); @@ -539,13 +539,13 @@ void bidib_state_lc_wait(t_bidib_node_address node_address, t_bidib_peripheral_p port.port0, port.port1, node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_peripherals_mutex); } /** * Logging utility for if a known or unknown train enters/exits a segment. - * Shall only be called with bidib_state_trains_rwlock >=read acquired, + * Shall only be called with bidib_trains_rwlock >=read acquired, * and with trackstate_trains_mutex acquired. * * @param detected if the train was detected (=entered, true) or left (=exited, false) a segment @@ -593,7 +593,7 @@ void bidib_state_log_train_detect(bool detected, const t_bidib_dcc_address *cons void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool occ) { // For bidib_state_log_train_detect and bidib_state_update_train_available - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available // (devnote: write) @@ -623,14 +623,14 @@ void bidib_state_bm_occ(t_bidib_node_address node_address, uint8_t number, bool } pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, uint8_t size, const uint8_t *const data) { t_bidib_segment_state_intern *segment_state; // For bidib_state_log_train_detect and bidib_state_update_train_available - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available // (devnote: write) @@ -667,7 +667,7 @@ void bidib_state_bm_multiple(t_bidib_node_address node_address, uint8_t number, bidib_state_update_train_available(); pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_void, @@ -675,7 +675,7 @@ void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_v // For bidib_state_get_segment_state_ref (devnote: write) pthread_mutex_lock(&trackstate_segments_mutex); // For bidib_state_get_board_ref_by_nodeaddr - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); const t_bidib_board *const board = bidib_state_get_board_ref_by_nodeaddr(node_address); if (board != NULL) { @@ -715,13 +715,13 @@ void bidib_state_bm_confidence(t_bidib_node_address node_address, uint8_t conf_v "No board configured for node address 0x%02x 0x%02x 0x%02x 0x00", node_address.top, node_address.sub, node_address.subsub); } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_segments_mutex); } /** * Check for new and lost dcc addresses in segment state and log accordingly. - * Shall only be called with bidib_state_trains_rwlock >= read acquired, + * Shall only be called with bidib_trains_rwlock >= read acquired, * and with trackstate_trains_mutex acquired. * * @param segment_state_intern_query the segment for which to log address changes, state with old addrs. @@ -789,7 +789,7 @@ void bidib_state_bm_address_log_changes( void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, uint8_t address_count, const uint8_t *const addresses) { // For bidib_state_update_train_available and bidib_state_bm_address_log_changes - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); // For bidib_state_get_segment_state_ref_by_nodeaddr and bidib_state_update_train_available // (devnote: write) @@ -834,7 +834,7 @@ void bidib_state_bm_address(t_bidib_node_address node_address, uint8_t number, } pthread_mutex_unlock(&trackstate_trains_mutex); pthread_mutex_unlock(&trackstate_segments_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } void bidib_state_bm_current(t_bidib_node_address node_address, uint8_t number, @@ -887,7 +887,7 @@ void bidib_state_bm_current(t_bidib_node_address node_address, uint8_t number, void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, uint8_t speedh) { // For bidib_state_get_train_state_ref_by_dccaddr - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); @@ -902,13 +902,13 @@ void bidib_state_bm_speed(t_bidib_dcc_address dcc_address, uint8_t speedl, uint8 dcc_address.addrl, dcc_address.addrh); } pthread_mutex_unlock(&trackstate_trains_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, uint8_t value, unsigned int action_id) { // For bidib_state_get_train_state_ref_by_dccaddr - pthread_rwlock_rdlock(&bidib_state_trains_rwlock); + pthread_rwlock_rdlock(&bidib_trains_rwlock); // For bidib_state_get_train_state_ref_by_dccaddr (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); @@ -962,7 +962,7 @@ void bidib_state_bm_dyn_state(t_bidib_dcc_address dcc_address, uint8_t dyn_num, dcc_address.addrl, dcc_address.addrh); } pthread_mutex_unlock(&trackstate_trains_mutex); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); } void bidib_state_boost_diagnostic(t_bidib_node_address node_address, uint8_t length, diff --git a/src/state/bidib_state_setter_intern.h b/src/state/bidib_state_setter_intern.h index cde5ebe..1ae763a 100644 --- a/src/state/bidib_state_setter_intern.h +++ b/src/state/bidib_state_setter_intern.h @@ -108,7 +108,7 @@ void bidib_state_cs_drive_ack(t_bidib_dcc_address dcc_address, uint8_t ack, /** * Sets the ack info for an dcc accessory. * Shall only be called with trackstate_accessories_mutex acquired, - * and bidib_state_boards_rwlock >= read lock acquired. + * and bidib_boards_rwlock >= read lock acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -119,7 +119,7 @@ void bidib_state_cs_accessory_ack(t_bidib_node_address node_address, /** * Sets the reported info about a manual train drive operation. - * Shall only be called with bidib_state_trains_rwlock >= read acquired. + * Shall only be called with bidib_trains_rwlock >= read acquired. * Note: uses trackstate_trains_mutex locally. * * @param params the parameters for the drive command. @@ -129,7 +129,7 @@ void bidib_state_cs_drive(t_bidib_cs_drive_mod params); /** * Sets the reported info about manual dcc accessory operation. * Shall only be called with trackstate_accessories_mutex acquired, - * and with bidib_state_boards_rwlock >= read acquired. + * and with bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param dcc_address the dcc address of the accessory. @@ -141,7 +141,7 @@ void bidib_state_cs_accessory_manual(t_bidib_node_address node_address, /** * Sets the new state for a dcc accessory. * Shall only be called with trackstate_accessories_mutex acquired, - * and with bidib_state_boards_rwlock >= read acquired. + * and with bidib_boards_rwlock >= read acquired. * * @param node_address the node address of the board. * @param params the parameters for the dcc accessory. diff --git a/src/transmission/bidib_transmission_receive.c b/src/transmission/bidib_transmission_receive.c index 7438510..6a61e34 100644 --- a/src/transmission/bidib_transmission_receive.c +++ b/src/transmission/bidib_transmission_receive.c @@ -218,7 +218,7 @@ static void bidib_log_received_message(const uint8_t *const addr_stack, uint8_t syslog_libbidib(LOG_DEBUG, "Message bytes: %s", hex_string); } -// Shall only be called with bidib_state_boards_rwlock >= read acquired. +// Shall only be called with bidib_boards_rwlock >= read acquired. static void bidib_log_sys_error(const uint8_t *const message, t_bidib_node_address node_address, unsigned int action_id) { @@ -254,7 +254,7 @@ static void bidib_log_sys_error(const uint8_t *const message, g_string_free(fault_name, TRUE); } -// Shall only be called with bidib_state_boards_rwlock >= read acquired. +// Shall only be called with bidib_boards_rwlock >= read acquired. static void bidib_log_boost_stat_error(const uint8_t *const message, t_bidib_node_address node_address, unsigned int action_id) { @@ -274,7 +274,7 @@ static void bidib_log_boost_stat_error(const uint8_t *const message, g_string_free(fault_name, TRUE); } -// Shall only be called with bidib_state_boards_rwlock >= read acquired. +// Shall only be called with bidib_boards_rwlock >= read acquired. static void bidib_log_boost_stat_okay(const uint8_t *const message, t_bidib_node_address node_address, unsigned int action_id) { @@ -380,10 +380,10 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, dcc_address.addrh = message[data_index + 1]; // Both for bidib_state_cs_accessory_ack (devnote: write for first) pthread_mutex_lock(&trackstate_accessories_mutex); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_state_cs_accessory_ack(node_address, dcc_address, message[data_index + 2]); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); free(message); break; @@ -401,9 +401,9 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, cs_drive_params.function2 = message[data_index + 6]; cs_drive_params.function3 = message[data_index + 7]; cs_drive_params.function4 = message[data_index + 8]; - pthread_rwlock_wrlock(&bidib_state_trains_rwlock); + pthread_rwlock_wrlock(&bidib_trains_rwlock); bidib_state_cs_drive(cs_drive_params); - pthread_rwlock_unlock(&bidib_state_trains_rwlock); + pthread_rwlock_unlock(&bidib_trains_rwlock); free(message); break; case MSG_CS_ACCESSORY_MANUAL: @@ -414,9 +414,9 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, dcc_address.addrh = message[data_index + 1]; // Both for bidib_state_cs_accessory_manual (devnote: write for first) pthread_mutex_lock(&trackstate_accessories_mutex); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_state_cs_accessory_manual(node_address, dcc_address, message[data_index + 2]); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); pthread_mutex_unlock(&trackstate_accessories_mutex); free(message); break; @@ -443,10 +443,10 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, bidib_log_received_message(addr_stack, seqnum, type, LOG_INFO, message, action_id); bidib_state_bm_occ(node_address, message[data_index], true); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); board = bidib_state_get_board_ref_by_nodeaddr(node_address); secack_on = board != NULL && board->secack_on; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); if (secack_on) { bidib_send_bm_mirror_occ(node_address, message[data_index], 0); bidib_flush(); @@ -459,10 +459,10 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, message, action_id); bidib_state_bm_occ(node_address, message[data_index], false); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); board = bidib_state_get_board_ref_by_nodeaddr(node_address); secack_on = board != NULL && board->secack_on; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); if (secack_on) { bidib_send_bm_mirror_free(node_address, message[data_index], 0); bidib_flush(); @@ -475,10 +475,10 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, message, action_id); bidib_state_bm_multiple(node_address, message[data_index], message[data_index + 1], &message[data_index + 2]); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); board = bidib_state_get_board_ref_by_nodeaddr(node_address); secack_on = board != NULL && board->secack_on; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); if (secack_on) { bidib_send_bm_mirror_multiple(node_address, message[data_index], message[data_index + 1], &message[data_index + 2], 0); @@ -582,16 +582,16 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, // add to error queue bidib_log_received_message(addr_stack, seqnum, type, LOG_ERR, message, action_id); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_log_boost_stat_error(message, node_address, action_id); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_uplink_error_queue_add(message, type, addr_stack); } else { bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, message, action_id); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_log_boost_stat_okay(message, node_address, action_id); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); free(message); } break; @@ -622,9 +622,9 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, // add to error message queue bidib_log_received_message(addr_stack, seqnum, type, LOG_DEBUG, message, action_id); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); bidib_log_sys_error(message, node_address, action_id); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); bidib_uplink_error_queue_add(message, type, addr_stack); break; case MSG_NODE_NA: @@ -639,10 +639,10 @@ void bidib_handle_received_message(uint8_t *message, uint8_t type, // add to message queue bidib_log_received_message(addr_stack, seqnum, type, LOG_INFO, message, action_id); - pthread_rwlock_rdlock(&bidib_state_boards_rwlock); + pthread_rwlock_rdlock(&bidib_boards_rwlock); board = bidib_state_get_board_ref_by_nodeaddr(node_address); secack_on = board != NULL && board->secack_on; - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); if (secack_on) { bidib_send_msg_bm_mirror_position(node_address, message[data_index], message[data_index + 1], diff --git a/test/unit/bidib_highlevel_message_tests.c b/test/unit/bidib_highlevel_message_tests.c index e074699..4bc445c 100644 --- a/test/unit/bidib_highlevel_message_tests.c +++ b/test/unit/bidib_highlevel_message_tests.c @@ -60,7 +60,7 @@ static void write_bytes(uint8_t* msg, int32_t len) { // Assume that the system receives a response to its request. static void board_receives_response(const uint8_t response_type) { - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); t_bidib_board *board_i; for (size_t i = 0; i < bidib_boards->len; i++) { board_i = &g_array_index(bidib_boards, t_bidib_board, i); @@ -72,16 +72,16 @@ static void board_receives_response(const uint8_t response_type) { 0x00 }; bidib_node_state_update(addr_stack, response_type); - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); return; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); } static void set_all_boards_and_trains_connected(void) { // For accessing bidib_boards - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); t_bidib_board *board_i; for (size_t i = 0; i < bidib_boards->len; i++) { board_i = &g_array_index(bidib_boards, t_bidib_board, i); @@ -89,7 +89,7 @@ static void set_all_boards_and_trains_connected(void) { board_i->connected = true; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); // For bidib_state_get_train_state_ref (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state = bidib_state_get_train_state_ref("train1"); diff --git a/test/unit/bidib_parallel_tests.c b/test/unit/bidib_parallel_tests.c index 88d2e54..6d58c1b 100644 --- a/test/unit/bidib_parallel_tests.c +++ b/test/unit/bidib_parallel_tests.c @@ -62,7 +62,7 @@ static void write_bytes(uint8_t* msg, int32_t len) { } static void set_all_boards_and_trains_connected(void) { - pthread_rwlock_wrlock(&bidib_state_boards_rwlock); + pthread_rwlock_wrlock(&bidib_boards_rwlock); t_bidib_board *board_i; for (size_t i = 0; i < bidib_boards->len; i++) { board_i = &g_array_index(bidib_boards, t_bidib_board, i); @@ -70,7 +70,7 @@ static void set_all_boards_and_trains_connected(void) { board_i->connected = true; } } - pthread_rwlock_unlock(&bidib_state_boards_rwlock); + pthread_rwlock_unlock(&bidib_boards_rwlock); // For bidib_state_get_train_state_ref (devnote: write) pthread_mutex_lock(&trackstate_trains_mutex); From c097281678b5584738be4a9f1f12f8b437b99833 Mon Sep 17 00:00:00 2001 From: Bernhard Luedtke Date: Wed, 4 Dec 2024 13:40:15 +0100 Subject: [PATCH 51/51] formatting/whitespace in bidib_state.c --- src/state/bidib_state.c | 140 +++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 73 deletions(-) diff --git a/src/state/bidib_state.c b/src/state/bidib_state.c index d355cc5..4a3ae47 100644 --- a/src/state/bidib_state.c +++ b/src/state/bidib_state.c @@ -53,35 +53,35 @@ GArray *bidib_trains = NULL; int bidib_state_init(const char *config_dir) { - bidib_initial_values.points = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_state_initial_value), 32); - bidib_initial_values.signals = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_state_initial_value), 32); - bidib_initial_values.peripherals = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_state_initial_value), 32); - bidib_initial_values.trains = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_state_train_initial_value), 16); - - bidib_track_state.points_board = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_board_accessory_state), 16); - bidib_track_state.points_dcc = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_dcc_accessory_state), 16); - bidib_track_state.signals_board = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_board_accessory_state), 16); - bidib_track_state.signals_dcc = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_dcc_accessory_state), 16); - bidib_track_state.peripherals = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_peripheral_state), 32); - bidib_track_state.reversers = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_reverser_state), 2); - bidib_track_state.segments = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_segment_state_intern), 256); - bidib_track_state.trains = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_train_state_intern), 16); - bidib_track_state.boosters = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_booster_state), 8); - bidib_track_state.track_outputs = g_array_sized_new(FALSE, FALSE, - sizeof(t_bidib_track_output_state), 8); + bidib_initial_values.points = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_state_initial_value), 32); + bidib_initial_values.signals = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_state_initial_value), 32); + bidib_initial_values.peripherals = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_state_initial_value), 32); + bidib_initial_values.trains = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_state_train_initial_value), 16); + + bidib_track_state.points_board = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_board_accessory_state), 16); + bidib_track_state.points_dcc = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_dcc_accessory_state), 16); + bidib_track_state.signals_board = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_board_accessory_state), 16); + bidib_track_state.signals_dcc = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_dcc_accessory_state), 16); + bidib_track_state.peripherals = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_peripheral_state), 32); + bidib_track_state.reversers = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_reverser_state), 2); + bidib_track_state.segments = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_segment_state_intern), 256); + bidib_track_state.trains = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_train_state_intern), 16); + bidib_track_state.boosters = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_booster_state), 8); + bidib_track_state.track_outputs = + g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_track_output_state), 8); bidib_boards = g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_board), 32); bidib_trains = g_array_sized_new(FALSE, FALSE, sizeof(t_bidib_train), 16); @@ -236,12 +236,13 @@ void bidib_state_query_occupancy(void) { uint8_t max_seg_addr = 0x00; for (size_t j = 0; j < board_i->segments->len; j++) { const t_bidib_segment_mapping *const seg_mapping = - &g_array_index(board_i->segments, t_bidib_segment_mapping, j); + &g_array_index(board_i->segments, t_bidib_segment_mapping, j); if (seg_mapping->addr > max_seg_addr) { max_seg_addr = seg_mapping->addr; } } - bidib_send_bm_get_range(board_i->node_addr, 0, (uint8_t) (((max_seg_addr / 8) + 1) * 8), 0); + bidib_send_bm_get_range(board_i->node_addr, 0, + (uint8_t) (((max_seg_addr / 8) + 1) * 8), 0); bidib_send_bm_addr_get_range(board_i->node_addr, 0, (uint8_t) (max_seg_addr + 1), 0); } } @@ -253,8 +254,8 @@ void bidib_state_set_board_features(void) { const t_bidib_board *const board_i = &g_array_index(bidib_boards, t_bidib_board, i); if (board_i->connected) { for (size_t j = 0; j < board_i->features->len; j++) { - const t_bidib_board_feature *const feature_j = &g_array_index(board_i->features, - t_bidib_board_feature, j); + const t_bidib_board_feature *const feature_j = + &g_array_index(board_i->features, t_bidib_board_feature, j); bidib_send_feature_set(board_i->node_addr, feature_j->number, feature_j->value, 0); } @@ -268,8 +269,8 @@ void bidib_state_set_board_features(void) { } else if (bidib_extract_msg_type(message) == MSG_FEATURE) { int first_data_byte = bidib_first_data_byte_index(message); for (size_t k = 0; k < board_i->features->len; k++) { - const t_bidib_board_feature *const feature_k = &g_array_index(board_i->features, - t_bidib_board_feature, k); + const t_bidib_board_feature *const feature_k = + &g_array_index(board_i->features, t_bidib_board_feature, k); if (feature_k->number == message[first_data_byte]) { if (feature_k->value != message[first_data_byte + 1]) { syslog_libbidib(LOG_ERR, @@ -307,33 +308,33 @@ void bidib_state_set_initial_values(void) { t_bidib_track_output_state *track_output_state; for (size_t i = 0; i < bidib_initial_values.points->len; i++) { - initial_value = &g_array_index( - bidib_initial_values.points, t_bidib_state_initial_value, i); + initial_value = + &g_array_index(bidib_initial_values.points, t_bidib_state_initial_value, i); bidib_switch_point(initial_value->id->str, initial_value->value->str); } for (size_t i = 0; i < bidib_initial_values.signals->len; i++) { - initial_value = &g_array_index( - bidib_initial_values.signals, t_bidib_state_initial_value, i); + initial_value = + &g_array_index(bidib_initial_values.signals, t_bidib_state_initial_value, i); bidib_set_signal(initial_value->id->str, initial_value->value->str); } for (size_t i = 0; i < bidib_initial_values.peripherals->len; i++) { - initial_value = &g_array_index( - bidib_initial_values.peripherals, t_bidib_state_initial_value, i); + initial_value = + &g_array_index(bidib_initial_values.peripherals, t_bidib_state_initial_value, i); bidib_set_peripheral(initial_value->id->str, initial_value->value->str); } for (size_t i = 0; i < bidib_initial_values.trains->len; i++) { - train_initial_value = &g_array_index( - bidib_initial_values.trains, t_bidib_state_train_initial_value, i); + train_initial_value = + &g_array_index(bidib_initial_values.trains, t_bidib_state_train_initial_value, i); ///NOTE: Technically, we need to protect this access of bidib_track_state.track_outputs // with trackstate_track_outputs_mutex, but due to what is being called in the loop body, // this is not really possible if we want to keep the lock ordering consistent. // At least not without significantly complicating a lot of the locking. for (size_t j = 0; j < bidib_track_state.track_outputs->len; j++) { - track_output_state = &g_array_index( - bidib_track_state.track_outputs, t_bidib_track_output_state, j); + track_output_state = + &g_array_index(bidib_track_state.track_outputs, t_bidib_track_output_state, j); if (track_output_state != NULL) { bidib_set_train_peripheral(train_initial_value->train->str, train_initial_value->id->str, train_initial_value->value, @@ -433,8 +434,7 @@ bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address) { for (size_t j = 0; j < tmp_board->points_dcc->len; j++) { const t_bidib_dcc_accessory_mapping *const tmp_dcc_mapping = - &g_array_index(tmp_board->points_dcc, - t_bidib_dcc_accessory_mapping, j); + &g_array_index(tmp_board->points_dcc, t_bidib_dcc_accessory_mapping, j); if (tmp_dcc_mapping->dcc_addr.addrl == dcc_address.addrl && tmp_dcc_mapping->dcc_addr.addrh == dcc_address.addrh) { pthread_rwlock_unlock(&bidib_boards_rwlock); @@ -444,8 +444,7 @@ bool bidib_state_dcc_addr_in_use(t_bidib_dcc_address dcc_address) { for (size_t j = 0; j < tmp_board->signals_dcc->len; j++) { const t_bidib_dcc_accessory_mapping *const tmp_dcc_mapping = - &g_array_index(tmp_board->signals_dcc, - t_bidib_dcc_accessory_mapping, j); + &g_array_index(tmp_board->signals_dcc, t_bidib_dcc_accessory_mapping, j); if (tmp_dcc_mapping->dcc_addr.addrl == dcc_address.addrl && tmp_dcc_mapping->dcc_addr.addrh == dcc_address.addrh) { pthread_rwlock_unlock(&bidib_boards_rwlock); @@ -700,8 +699,8 @@ void bidib_state_update_train_available(void) { struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); for (size_t i = 0; i < bidib_track_state.trains->len; i++) { - train_state = &g_array_index( - bidib_track_state.trains, t_bidib_train_state_intern, i); + train_state = + &g_array_index(bidib_track_state.trains, t_bidib_train_state_intern, i); query = bidib_get_train_position_intern(train_state->id->str); if (query.length > 0) { train_state->orientation = @@ -736,8 +735,8 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_accessories_mutex); t_bidib_board_accessory_state *board_accessory_state; for (size_t i = 0; i < bidib_track_state.points_board->len; i++) { - board_accessory_state = &g_array_index(bidib_track_state.points_board, - t_bidib_board_accessory_state, i); + board_accessory_state = + &g_array_index(bidib_track_state.points_board, t_bidib_board_accessory_state, i); board_accessory_state->data.state_id = NULL; board_accessory_state->data.state_value = 0x00; board_accessory_state->data.execution_state = BIDIB_EXEC_STATE_REACHED; @@ -746,8 +745,8 @@ void bidib_state_reset(void) { t_bidib_dcc_accessory_state *dcc_accessory_state; for (size_t i = 0; i < bidib_track_state.points_dcc->len; i++) { - dcc_accessory_state = &g_array_index(bidib_track_state.points_dcc, - t_bidib_dcc_accessory_state, i); + dcc_accessory_state = + &g_array_index(bidib_track_state.points_dcc, t_bidib_dcc_accessory_state, i); dcc_accessory_state->data.state_id = NULL; dcc_accessory_state->data.state_value = 0x00; dcc_accessory_state->data.time_unit = BIDIB_TIMEUNIT_MILLISECONDS; @@ -755,8 +754,8 @@ void bidib_state_reset(void) { } for (size_t i = 0; i < bidib_track_state.signals_board->len; i++) { - board_accessory_state = &g_array_index(bidib_track_state.signals_board, - t_bidib_board_accessory_state, i); + board_accessory_state = + &g_array_index(bidib_track_state.signals_board, t_bidib_board_accessory_state, i); board_accessory_state->data.state_id = NULL; board_accessory_state->data.state_value = 0x00; board_accessory_state->data.execution_state = BIDIB_EXEC_STATE_REACHED; @@ -764,8 +763,8 @@ void bidib_state_reset(void) { } for (size_t i = 0; i < bidib_track_state.signals_dcc->len; i++) { - dcc_accessory_state = &g_array_index(bidib_track_state.signals_dcc, - t_bidib_dcc_accessory_state, i); + dcc_accessory_state = + &g_array_index(bidib_track_state.signals_dcc, t_bidib_dcc_accessory_state, i); dcc_accessory_state->data.state_id = NULL; dcc_accessory_state->data.state_value = 0x00; dcc_accessory_state->data.coil_on = 0x00; @@ -778,8 +777,8 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_peripherals_mutex); t_bidib_peripheral_state *peripheral_state; for (size_t i = 0; i < bidib_track_state.peripherals->len; i++) { - peripheral_state = &g_array_index(bidib_track_state.peripherals, - t_bidib_peripheral_state, i); + peripheral_state = + &g_array_index(bidib_track_state.peripherals, t_bidib_peripheral_state, i); peripheral_state->data.state_id = NULL; peripheral_state->data.state_value = 0x00; peripheral_state->data.time_unit = BIDIB_TIMEUNIT_MILLISECONDS; @@ -791,8 +790,7 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_segments_mutex); t_bidib_segment_state_intern *segment_state; for (size_t i = 0; i < bidib_track_state.segments->len; i++) { - segment_state = &g_array_index(bidib_track_state.segments, - t_bidib_segment_state_intern, i); + segment_state = &g_array_index(bidib_track_state.segments, t_bidib_segment_state_intern, i); segment_state->occupied = false; segment_state->confidence.conf_void = false; segment_state->confidence.freeze = false; @@ -811,8 +809,7 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_reversers_mutex); t_bidib_reverser_state *reverser_state; for (size_t i = 0; i < bidib_track_state.reversers->len; i++) { - reverser_state = &g_array_index(bidib_track_state.reversers, - t_bidib_reverser_state, i); + reverser_state = &g_array_index(bidib_track_state.reversers, t_bidib_reverser_state, i); reverser_state->data.state_id = NULL; reverser_state->data.state_value = BIDIB_REV_EXEC_STATE_UNKNOWN; } @@ -822,8 +819,7 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_trains_mutex); t_bidib_train_state_intern *train_state; for (size_t i = 0; i < bidib_track_state.trains->len; i++) { - train_state = &g_array_index(bidib_track_state.trains, - t_bidib_train_state_intern, i); + train_state = &g_array_index(bidib_track_state.trains, t_bidib_train_state_intern, i); train_state->on_track = false; train_state->orientation = BIDIB_TRAIN_ORIENTATION_LEFT; train_state->set_speed_step = 0; @@ -831,8 +827,7 @@ void bidib_state_reset(void) { train_state->set_is_forwards = true; train_state->ack = BIDIB_DCC_ACK_PENDING; for (size_t j = 0; j < train_state->peripherals->len; j++) { - g_array_index(train_state->peripherals, - t_bidib_train_peripheral_state, j).state = 0x00; + g_array_index(train_state->peripherals, t_bidib_train_peripheral_state, j).state = 0x00; } train_state->decoder_state.signal_quality_known = false; train_state->decoder_state.temp_known = false; @@ -846,8 +841,7 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_boosters_mutex); t_bidib_booster_state *booster_state; for (size_t i = 0; i < bidib_track_state.boosters->len; i++) { - booster_state = &g_array_index(bidib_track_state.boosters, - t_bidib_booster_state, i); + booster_state = &g_array_index(bidib_track_state.boosters, t_bidib_booster_state, i); booster_state->data.power_state = BIDIB_BSTR_OFF; booster_state->data.power_state_simple = bidib_booster_normal_to_simple( booster_state->data.power_state); @@ -861,8 +855,8 @@ void bidib_state_reset(void) { pthread_mutex_lock(&trackstate_track_outputs_mutex); t_bidib_track_output_state *track_output_state; for (size_t i = 0; i < bidib_track_state.track_outputs->len; i++) { - track_output_state = &g_array_index(bidib_track_state.track_outputs, - t_bidib_track_output_state, i); + track_output_state = + &g_array_index(bidib_track_state.track_outputs, t_bidib_track_output_state, i); track_output_state->cs_state = BIDIB_CS_OFF; } pthread_mutex_unlock(&trackstate_track_outputs_mutex);