1 /* 2 * Copyright (c) 2002, Intel Corporation. All rights reserved. 3 * Created by: bing.wei.liu REMOVE-THIS AT intel DOT com 4 * This file is licensed under the GPL license. For the full content 5 * of this license, see the COPYING file at the top level of this 6 * source tree. 7 8 * Test that pthread_mutex_unlock() 9 * If there are threads blocked on the mutex object referenced by 'mutex' when 10 * pthread_mutex_unlock() is called, resulting in the mutex becoming available, 11 * the scheduling policy shall determine which thread shall acquire the mutex. 12 13 * NOTES: 14 * The default scheduling policy is implementation dependent, thus this case 15 * will only demo the scheduling sequence instead of testing it. 16 17 * Steps: 18 * -- Initialize a mutex to protect a global variable 'value' 19 * -- Create N threads. Each is looped M times to acquire the mutex, 20 increase the value, and then release the mutex. 21 * -- Check if the value has increased properly (M*N); a broken mutex 22 implementation may cause lost augments. 23 * 24 */ 25 26 #define _XOPEN_SOURCE 600 27 28 #include <pthread.h> 29 #include <stdio.h> 30 #include <unistd.h> 31 #include "posixtest.h" 32 33 #define THREAD_NUM 6 34 #define LOOPS 3 35 36 void *func(void *parm); 37 38 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 39 int value; /* value protected by mutex */ 40 41 int main(void) 42 { 43 int i, rc; 44 pthread_t threads[THREAD_NUM]; 45 46 /* Create threads */ 47 fprintf(stderr, "Creating %d threads\n", THREAD_NUM); 48 for (i = 0; i < THREAD_NUM; ++i) 49 rc = pthread_create(&threads[i], NULL, func, NULL); 50 51 /* Wait to join all threads */ 52 for (i = 0; i < THREAD_NUM; ++i) 53 pthread_join(threads[i], NULL); 54 pthread_mutex_destroy(&mutex); 55 56 /* Check if the final value is as expected */ 57 if (value != (THREAD_NUM) * LOOPS) { 58 fprintf(stderr, "Using %d threads and each loops %d times\n", 59 THREAD_NUM, LOOPS); 60 fprintf(stderr, "Final value must be %d instead of %d\n", 61 (THREAD_NUM) * LOOPS, value); 62 return PTS_UNRESOLVED; 63 } 64 65 printf("Test PASSED\n"); 66 return PTS_PASS; 67 } 68 69 void *func(void *parm) 70 { 71 int i, tmp; 72 int rc = 0; 73 pthread_t self = pthread_self(); 74 75 /* Loopd M times to acquire the mutex, increase the value, 76 and then release the mutex. */ 77 78 for (i = 0; i < LOOPS; ++i) { 79 rc = pthread_mutex_lock(&mutex); 80 if (rc != 0) { 81 fprintf(stderr, 82 "Error on pthread_mutex_lock(), rc=%d\n", rc); 83 return (void *)(PTS_UNRESOLVED); 84 } 85 86 tmp = value; 87 tmp = tmp + 1; 88 fprintf(stderr, "Thread(0x%p) holds the mutex\n", (void *)self); 89 usleep(1000); /* delay the increasement operation */ 90 value = tmp; 91 92 rc = pthread_mutex_unlock(&mutex); 93 if (rc != 0) { 94 fprintf(stderr, 95 "Error on pthread_mutex_unlock(), rc=%d\n", rc); 96 return (void *)(PTS_UNRESOLVED); 97 } 98 sleep(1); 99 } 100 pthread_exit(0); 101 return (void *)(0); 102 } 103