119a4ff53SMathieu Desnoyers // SPDX-License-Identifier: GPL-2.0
219a4ff53SMathieu Desnoyers #define _GNU_SOURCE
319a4ff53SMathieu Desnoyers #include <linux/membarrier.h>
419a4ff53SMathieu Desnoyers #include <syscall.h>
519a4ff53SMathieu Desnoyers #include <stdio.h>
619a4ff53SMathieu Desnoyers #include <errno.h>
719a4ff53SMathieu Desnoyers #include <string.h>
819a4ff53SMathieu Desnoyers #include <pthread.h>
919a4ff53SMathieu Desnoyers 
1019a4ff53SMathieu Desnoyers #include "membarrier_test_impl.h"
1119a4ff53SMathieu Desnoyers 
1219a4ff53SMathieu Desnoyers static int thread_ready, thread_quit;
1319a4ff53SMathieu Desnoyers static pthread_mutex_t test_membarrier_thread_mutex =
1419a4ff53SMathieu Desnoyers 	PTHREAD_MUTEX_INITIALIZER;
1519a4ff53SMathieu Desnoyers static pthread_cond_t test_membarrier_thread_cond =
1619a4ff53SMathieu Desnoyers 	PTHREAD_COND_INITIALIZER;
1719a4ff53SMathieu Desnoyers 
test_membarrier_thread(void * arg)1819a4ff53SMathieu Desnoyers void *test_membarrier_thread(void *arg)
1919a4ff53SMathieu Desnoyers {
2019a4ff53SMathieu Desnoyers 	pthread_mutex_lock(&test_membarrier_thread_mutex);
2119a4ff53SMathieu Desnoyers 	thread_ready = 1;
2219a4ff53SMathieu Desnoyers 	pthread_cond_broadcast(&test_membarrier_thread_cond);
2319a4ff53SMathieu Desnoyers 	pthread_mutex_unlock(&test_membarrier_thread_mutex);
2419a4ff53SMathieu Desnoyers 
2519a4ff53SMathieu Desnoyers 	pthread_mutex_lock(&test_membarrier_thread_mutex);
2619a4ff53SMathieu Desnoyers 	while (!thread_quit)
2719a4ff53SMathieu Desnoyers 		pthread_cond_wait(&test_membarrier_thread_cond,
2819a4ff53SMathieu Desnoyers 				  &test_membarrier_thread_mutex);
2919a4ff53SMathieu Desnoyers 	pthread_mutex_unlock(&test_membarrier_thread_mutex);
3019a4ff53SMathieu Desnoyers 
3119a4ff53SMathieu Desnoyers 	return NULL;
3219a4ff53SMathieu Desnoyers }
3319a4ff53SMathieu Desnoyers 
test_mt_membarrier(void)3419a4ff53SMathieu Desnoyers static int test_mt_membarrier(void)
3519a4ff53SMathieu Desnoyers {
3619a4ff53SMathieu Desnoyers 	int i;
3719a4ff53SMathieu Desnoyers 	pthread_t test_thread;
3819a4ff53SMathieu Desnoyers 
3919a4ff53SMathieu Desnoyers 	pthread_create(&test_thread, NULL,
4019a4ff53SMathieu Desnoyers 		       test_membarrier_thread, NULL);
4119a4ff53SMathieu Desnoyers 
4219a4ff53SMathieu Desnoyers 	pthread_mutex_lock(&test_membarrier_thread_mutex);
4319a4ff53SMathieu Desnoyers 	while (!thread_ready)
4419a4ff53SMathieu Desnoyers 		pthread_cond_wait(&test_membarrier_thread_cond,
4519a4ff53SMathieu Desnoyers 				  &test_membarrier_thread_mutex);
4619a4ff53SMathieu Desnoyers 	pthread_mutex_unlock(&test_membarrier_thread_mutex);
4719a4ff53SMathieu Desnoyers 
4819a4ff53SMathieu Desnoyers 	test_membarrier_fail();
4919a4ff53SMathieu Desnoyers 
5019a4ff53SMathieu Desnoyers 	test_membarrier_success();
5119a4ff53SMathieu Desnoyers 
5219a4ff53SMathieu Desnoyers 	pthread_mutex_lock(&test_membarrier_thread_mutex);
5319a4ff53SMathieu Desnoyers 	thread_quit = 1;
5419a4ff53SMathieu Desnoyers 	pthread_cond_broadcast(&test_membarrier_thread_cond);
5519a4ff53SMathieu Desnoyers 	pthread_mutex_unlock(&test_membarrier_thread_mutex);
5619a4ff53SMathieu Desnoyers 
5719a4ff53SMathieu Desnoyers 	pthread_join(test_thread, NULL);
5819a4ff53SMathieu Desnoyers 
5919a4ff53SMathieu Desnoyers 	return 0;
6019a4ff53SMathieu Desnoyers }
6119a4ff53SMathieu Desnoyers 
main(int argc,char ** argv)6219a4ff53SMathieu Desnoyers int main(int argc, char **argv)
6319a4ff53SMathieu Desnoyers {
6419a4ff53SMathieu Desnoyers 	ksft_print_header();
65*d74f87f3SMichal Clapinski 	ksft_set_plan(16);
6619a4ff53SMathieu Desnoyers 
6719a4ff53SMathieu Desnoyers 	test_membarrier_query();
6819a4ff53SMathieu Desnoyers 
6919a4ff53SMathieu Desnoyers 	/* Multi-threaded */
7019a4ff53SMathieu Desnoyers 	test_mt_membarrier();
7119a4ff53SMathieu Desnoyers 
7219a4ff53SMathieu Desnoyers 	return ksft_exit_pass();
7319a4ff53SMathieu Desnoyers }
74