[LTP] [PATCH v2 1/2] Enhance Thread Safety in Record Counting
Vishal Chourasia
vishalc@linux.ibm.com
Tue Aug 15 11:30:47 CEST 2023
This patch addresses a thread safety concern in record counting. Originally,
the design leveraged a global `records_read` variable to aggregate counts from
different threads. This method was devoid of locks, leading to potential race
conditions. To remedy this:
- Introduced a thread-local variable, `records_thread`, for each thread to
store its record count.
- Upon thread joining, the accumulated total from each `records_thread` is safely
captured, ensuring accurate and race-free counting.
The overall change enhances thread safety, especially in multi-threaded
environments, and ensures the correct count is fetched without race conditions.
Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.vnet.ibm.com>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
---
utils/benchmark/ebizzy-0.3/ebizzy.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/utils/benchmark/ebizzy-0.3/ebizzy.c b/utils/benchmark/ebizzy-0.3/ebizzy.c
index 54b047130..ae0981fbd 100644
--- a/utils/benchmark/ebizzy-0.3/ebizzy.c
+++ b/utils/benchmark/ebizzy-0.3/ebizzy.c
@@ -50,6 +50,7 @@
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <stdint.h>
#include "ebizzy.h"
@@ -83,7 +84,6 @@ static char **hole_mem;
static unsigned int page_size;
static time_t start_time;
static volatile int threads_go;
-static unsigned int records_read;
static void usage(void)
{
@@ -366,13 +366,13 @@ static inline unsigned int rand_num(unsigned int max, unsigned int *state)
*
*/
-static unsigned int search_mem(void)
+static uintptr_t search_mem(void)
{
record_t key, *found;
record_t *src, *copy;
unsigned int chunk;
size_t copy_size = chunk_size;
- unsigned int i;
+ uintptr_t i;
unsigned int state = 0;
for (i = 0; threads_go == 1; i++) {
@@ -423,6 +423,8 @@ static unsigned int search_mem(void)
static void *thread_run(void *arg __attribute__((unused)))
{
+ uintptr_t records_thread;
+
if (verbose > 1)
printf("Thread started\n");
@@ -430,13 +432,13 @@ static void *thread_run(void *arg __attribute__((unused)))
while (threads_go == 0) ;
- records_read += search_mem();
+ records_thread = search_mem();
if (verbose > 1)
printf("Thread finished, %f seconds\n",
difftime(time(NULL), start_time));
- return NULL;
+ return (void *)records_thread;
}
static struct timeval difftimeval(struct timeval *end, struct timeval *start)
@@ -454,6 +456,7 @@ static void start_threads(void)
unsigned int i;
struct rusage start_ru, end_ru;
struct timeval usr_time, sys_time;
+ uintptr_t records_read = 0;
int err;
if (verbose)
@@ -484,18 +487,20 @@ static void start_threads(void)
*/
for (i = 0; i < threads; i++) {
- err = pthread_join(thread_array[i], NULL);
+ uintptr_t record_thread;
+ err = pthread_join(thread_array[i], (void *)&record_thread);
if (err) {
fprintf(stderr, "Error joining thread %d\n", i);
exit(1);
}
+ records_read += record_thread;
}
if (verbose)
printf("Threads finished\n");
- printf("%u records/s\n",
- (unsigned int)(((double)records_read) / elapsed));
+ printf("%tu records/s\n",
+ (uintptr_t)(((double)records_read) / elapsed));
usr_time = difftimeval(&end_ru.ru_utime, &start_ru.ru_utime);
sys_time = difftimeval(&end_ru.ru_stime, &start_ru.ru_stime);
--
2.39.3
More information about the ltp
mailing list