brintos

brintos / linux-shallow public Read only

0
0
Text · 4.3 KiB · 60ab025 Raw
170 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * POWER Data Stream Control Register (DSCR) default test4 *5 * This test modifies the system wide default DSCR through6 * it's sysfs interface and then verifies that all threads7 * see the correct changed DSCR value immediately.8 *9 * Copyright 2012, Anton Blanchard, IBM Corporation.10 * Copyright 2015, Anshuman Khandual, IBM Corporation.11 */12 13#define _GNU_SOURCE14 15#include "dscr.h"16 17#include <pthread.h>18#include <semaphore.h>19#include <unistd.h>20 21static void *dscr_default_lockstep_writer(void *arg)22{23	sem_t *reader_sem = (sem_t *)arg;24	sem_t *writer_sem = (sem_t *)arg + 1;25	unsigned long expected_dscr = 0;26 27	for (int i = 0; i < COUNT; i++) {28		FAIL_IF_EXIT(sem_wait(writer_sem));29 30		set_default_dscr(expected_dscr);31		expected_dscr = (expected_dscr + 1) % DSCR_MAX;32 33		FAIL_IF_EXIT(sem_post(reader_sem));34	}35 36	return NULL;37}38 39int dscr_default_lockstep_test(void)40{41	pthread_t writer;42	sem_t rw_semaphores[2];43	sem_t *reader_sem = &rw_semaphores[0];44	sem_t *writer_sem = &rw_semaphores[1];45	unsigned long expected_dscr = 0;46 47	SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));48 49	FAIL_IF(sem_init(reader_sem, 0, 0));50	FAIL_IF(sem_init(writer_sem, 0, 1));  /* writer starts first */51	FAIL_IF(bind_to_cpu(BIND_CPU_ANY) < 0);52	FAIL_IF(pthread_create(&writer, NULL, dscr_default_lockstep_writer, (void *)rw_semaphores));53 54	for (int i = 0; i < COUNT ; i++) {55		FAIL_IF(sem_wait(reader_sem));56 57		FAIL_IF(get_dscr() != expected_dscr);58		FAIL_IF(get_dscr_usr() != expected_dscr);59 60		expected_dscr = (expected_dscr + 1) % DSCR_MAX;61 62		FAIL_IF(sem_post(writer_sem));63	}64 65	FAIL_IF(pthread_join(writer, NULL));66	FAIL_IF(sem_destroy(reader_sem));67	FAIL_IF(sem_destroy(writer_sem));68 69	return 0;70}71 72struct random_thread_args {73	pthread_t thread_id;74	unsigned long *expected_system_dscr;75	pthread_rwlock_t *rw_lock;76	pthread_barrier_t *barrier;77};78 79static void *dscr_default_random_thread(void *in)80{81	struct random_thread_args *args = (struct random_thread_args *)in;82	unsigned long *expected_dscr_p = args->expected_system_dscr;83	pthread_rwlock_t *rw_lock = args->rw_lock;84	int err;85 86	srand(gettid());87 88	err = pthread_barrier_wait(args->barrier);89	FAIL_IF_EXIT(err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD);90 91	for (int i = 0; i < COUNT; i++) {92		unsigned long expected_dscr;93		unsigned long current_dscr;94		unsigned long current_dscr_usr;95 96		FAIL_IF_EXIT(pthread_rwlock_rdlock(rw_lock));97		expected_dscr = *expected_dscr_p;98		current_dscr = get_dscr();99		current_dscr_usr = get_dscr_usr();100		FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock));101 102		FAIL_IF_EXIT(current_dscr != expected_dscr);103		FAIL_IF_EXIT(current_dscr_usr != expected_dscr);104 105		if (rand() % 10 == 0) {106			unsigned long next_dscr;107 108			FAIL_IF_EXIT(pthread_rwlock_wrlock(rw_lock));109			next_dscr = (*expected_dscr_p + 1) % DSCR_MAX;110			set_default_dscr(next_dscr);111			*expected_dscr_p = next_dscr;112			FAIL_IF_EXIT(pthread_rwlock_unlock(rw_lock));113		}114	}115 116	pthread_exit((void *)0);117}118 119int dscr_default_random_test(void)120{121	struct random_thread_args threads[THREADS];122	unsigned long expected_system_dscr = 0;123	pthread_rwlockattr_t rwlock_attr;124	pthread_rwlock_t rw_lock;125	pthread_barrier_t barrier;126 127	SKIP_IF(!have_hwcap2(PPC_FEATURE2_DSCR));128 129	FAIL_IF(pthread_rwlockattr_setkind_np(&rwlock_attr,130					      PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP));131	FAIL_IF(pthread_rwlock_init(&rw_lock, &rwlock_attr));132	FAIL_IF(pthread_barrier_init(&barrier, NULL, THREADS));133 134	set_default_dscr(expected_system_dscr);135 136	for (int i = 0; i < THREADS; i++) {137		threads[i].expected_system_dscr = &expected_system_dscr;138		threads[i].rw_lock = &rw_lock;139		threads[i].barrier = &barrier;140 141		FAIL_IF(pthread_create(&threads[i].thread_id, NULL,142				       dscr_default_random_thread, (void *)&threads[i]));143	}144 145	for (int i = 0; i < THREADS; i++)146		FAIL_IF(pthread_join(threads[i].thread_id, NULL));147 148	FAIL_IF(pthread_barrier_destroy(&barrier));149	FAIL_IF(pthread_rwlock_destroy(&rw_lock));150 151	return 0;152}153 154int main(int argc, char *argv[])155{156	unsigned long orig_dscr_default = 0;157	int err = 0;158 159	if (have_hwcap2(PPC_FEATURE2_DSCR))160		orig_dscr_default = get_default_dscr();161 162	err |= test_harness(dscr_default_lockstep_test, "dscr_default_lockstep_test");163	err |= test_harness(dscr_default_random_test, "dscr_default_random_test");164 165	if (have_hwcap2(PPC_FEATURE2_DSCR))166		set_default_dscr(orig_dscr_default);167 168	return err;169}170