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_lock() 9 * shall lock the mutex object referenced by 'mutex'. If the mutex is 10 * already locked, the calling thread shall block until the mutex becomes 11 * available. This operation shall return with the mutex object referenced 12 * by 'mutex' in the locked state with the calling thread as its owner. 13 14 * Steps: 15 * -- Initialize a mutex to protect a global variable 'value' 16 * -- Create N threads. Each is looped M times to acquire the mutex, 17 * increase the value, and then release the mutex. 18 * -- Check if the value has increased properly (M*N); a broken mutex 19 * implementation may cause lost augments. 20 * 21 */ 22 23 #define _XOPEN_SOURCE 600 24 25 #include <pthread.h> 26 #include <stdio.h> 27 #include <unistd.h> 28 #include "posixtest.h" 29 30 #define THREAD_NUM 5 31 #define LOOPS 4 32 33 void *f1(void *parm); 34 35 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 36 int value; /* value protected by mutex */ 37 38 int main(void) 39 { 40 int i, rc; 41 pthread_attr_t pta; 42 pthread_t threads[THREAD_NUM]; 43 //pthread_t self = pthread_self(); 44 45 pthread_attr_init(&pta); 46 pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE); 47 48 /* Create threads */ 49 fprintf(stderr, "Creating %d threads\n", THREAD_NUM); 50 for (i = 0; i < THREAD_NUM; ++i) 51 rc = pthread_create(&threads[i], &pta, f1, NULL); 52 53 /* Wait to join all threads */ 54 for (i = 0; i < THREAD_NUM; ++i) 55 pthread_join(threads[i], NULL); 56 pthread_attr_destroy(&pta); 57 pthread_mutex_destroy(&mutex); 58 59 /* Check if the final value is as expected */ 60 if (value != (THREAD_NUM) * LOOPS) { 61 fprintf(stderr, "Using %d threads and each loops %d times\n", 62 THREAD_NUM, LOOPS); 63 fprintf(stderr, "Final value must be %d instead of %d\n", 64 (THREAD_NUM) * LOOPS, value); 65 printf("Test FAILED\n"); 66 return PTS_FAIL; 67 } 68 69 printf("Test PASSED\n"); 70 return PTS_PASS; 71 } 72 73 void *f1(void *parm) 74 { 75 int i, tmp; 76 int rc = 0; 77 pthread_t self = pthread_self(); 78 79 /* Loopd M times to acquire the mutex, increase the value, 80 and then release the mutex. */ 81 82 for (i = 0; i < LOOPS; ++i) { 83 rc = pthread_mutex_lock(&mutex); 84 if (rc != 0) { 85 fprintf(stderr, 86 "Error on pthread_mutex_lock(), rc=%d\n", rc); 87 return (void *)(PTS_FAIL); 88 } 89 90 tmp = value; 91 tmp = tmp + 1; 92 fprintf(stderr, "Thread(0x%p) holds the mutex\n", (void *)self); 93 usleep(1000); /* delay the increasement operation */ 94 value = tmp; 95 96 rc = pthread_mutex_unlock(&mutex); 97 if (rc != 0) { 98 fprintf(stderr, 99 "Error on pthread_mutex_unlock(), rc=%d\n", rc); 100 return (void *)(PTS_UNRESOLVED); 101 } 102 sleep(1); 103 } 104 pthread_exit(0); 105 return (void *)(0); 106 } 107