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 33void *f1(void *parm); 34 35pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 36int value; /* value protected by mutex */ 37 38int main() 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", THREAD_NUM, LOOPS); 62 fprintf(stderr,"Final value must be %d instead of %d\n", (THREAD_NUM)*LOOPS, value); 63 printf("Test FAILED\n"); 64 return PTS_FAIL; 65 } 66 67 printf("Test PASSED\n"); 68 return PTS_PASS; 69} 70 71void *f1(void *parm) 72{ 73 int i, tmp; 74 int rc = 0; 75 pthread_t self = pthread_self(); 76 77 /* Loopd M times to acquire the mutex, increase the value, 78 and then release the mutex. */ 79 80 for (i=0; i<LOOPS; ++i) { 81 rc = pthread_mutex_lock(&mutex); 82 if(rc!=0) { 83 fprintf(stderr,"Error on pthread_mutex_lock(), rc=%d\n", rc); 84 return (void*)(PTS_FAIL); 85 } 86 87 tmp = value; 88 tmp = tmp+1; 89 fprintf(stderr,"Thread(0x%p) holds the mutex\n",(void*)self); 90 usleep(1000); /* delay the increasement operation */ 91 value = tmp; 92 93 rc = pthread_mutex_unlock(&mutex); 94 if(rc!=0) { 95 fprintf(stderr,"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