1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009-2010 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci/* 30bf215546Sopenharmony_ci * Test case for util_barrier. 31bf215546Sopenharmony_ci * 32bf215546Sopenharmony_ci * The test succeeds if no thread exits before all the other threads reach 33bf215546Sopenharmony_ci * the barrier. 34bf215546Sopenharmony_ci */ 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include <stdio.h> 38bf215546Sopenharmony_ci#include <stdlib.h> 39bf215546Sopenharmony_ci#include <string.h> 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include "util/os_time.h" 42bf215546Sopenharmony_ci#include "util/u_atomic.h" 43bf215546Sopenharmony_ci#include "util/u_thread.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#define NUM_THREADS 10 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistatic int verbosity = 0; 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic thrd_t threads[NUM_THREADS]; 51bf215546Sopenharmony_cistatic util_barrier barrier; 52bf215546Sopenharmony_cistatic int thread_ids[NUM_THREADS]; 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_cistatic volatile int waiting = 0; 55bf215546Sopenharmony_cistatic volatile int proceeded = 0; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci#define LOG(fmt, ...) \ 59bf215546Sopenharmony_ci if (verbosity > 0) { \ 60bf215546Sopenharmony_ci fprintf(stdout, fmt, ##__VA_ARGS__); \ 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci#define CHECK(_cond) \ 64bf215546Sopenharmony_ci if (!(_cond)) { \ 65bf215546Sopenharmony_ci fprintf(stderr, "%s:%u: `%s` failed\n", __FILE__, __LINE__, #_cond); \ 66bf215546Sopenharmony_ci _exit(EXIT_FAILURE); \ 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic int 71bf215546Sopenharmony_cithread_function(void *thread_data) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci int thread_id = *((int *) thread_data); 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci LOG("thread %d starting\n", thread_id); 76bf215546Sopenharmony_ci os_time_sleep(thread_id * 100 * 1000); 77bf215546Sopenharmony_ci LOG("thread %d before barrier\n", thread_id); 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci CHECK(p_atomic_read(&proceeded) == 0); 80bf215546Sopenharmony_ci p_atomic_inc(&waiting); 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci util_barrier_wait(&barrier); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci CHECK(p_atomic_read(&waiting) == NUM_THREADS); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci p_atomic_inc(&proceeded); 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci LOG("thread %d exiting\n", thread_id); 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci return 0; 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ciint main(int argc, char *argv[]) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci int i; 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci for (i = 1; i < argc; ++i) { 99bf215546Sopenharmony_ci const char *arg = argv[i]; 100bf215546Sopenharmony_ci if (strcmp(arg, "-v") == 0) { 101bf215546Sopenharmony_ci ++verbosity; 102bf215546Sopenharmony_ci } else { 103bf215546Sopenharmony_ci fprintf(stderr, "error: unrecognized option `%s`\n", arg); 104bf215546Sopenharmony_ci exit(EXIT_FAILURE); 105bf215546Sopenharmony_ci } 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci // Disable buffering 109bf215546Sopenharmony_ci setbuf(stdout, NULL); 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci LOG("pipe_barrier_test starting\n"); 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci util_barrier_init(&barrier, NUM_THREADS); 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci for (i = 0; i < NUM_THREADS; i++) { 116bf215546Sopenharmony_ci thread_ids[i] = i; 117bf215546Sopenharmony_ci u_thread_create(threads + i, thread_function, (void *) &thread_ids[i]); 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci for (i = 0; i < NUM_THREADS; i++ ) { 121bf215546Sopenharmony_ci thrd_join(threads[i], NULL); 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci CHECK(p_atomic_read(&proceeded) == NUM_THREADS); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci util_barrier_destroy(&barrier); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci LOG("pipe_barrier_test exiting\n"); 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci return 0; 131bf215546Sopenharmony_ci} 132