1a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin/* 2a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * Copyright (c) 2002, Intel Corporation. All rights reserved. 3a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * Created by: bing.wei.liu REMOVE-THIS AT intel DOT com 4a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * This file is licensed under the GPL license. For the full content 5a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * of this license, see the COPYING file at the top level of this 6a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * source tree. 7a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 8a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * Test that pthread_mutex_lock() 9a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * shall lock the mutex object referenced by 'mutex'. If the mutex is 10ce5771f70cec4261a9c5d0682cc290ecd80e8468Paul Duffin * already locked, the calling thread shall block until the mutex becomes 11a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * available. This operation shall return with the mutex object referenced 12a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * by 'mutex' in the locked state with the calling thread as its owner. 13a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 14a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * Steps: 15a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin * -- Initialize a mutex to protect a global variable 'value' 16747cc2ad6a92424a7e64de5a4f325ab7180df6d2Paul Duffin * -- Create N threads. Each is looped M times to acquire the mutex, 17747cc2ad6a92424a7e64de5a4f325ab7180df6d2Paul Duffin * increase the value, and then release the mutex. 18747cc2ad6a92424a7e64de5a4f325ab7180df6d2Paul Duffin * -- Check if the value has increased properly (M*N); a broken mutex 19747cc2ad6a92424a7e64de5a4f325ab7180df6d2Paul Duffin * implementation may cause lost augments. 20747cc2ad6a92424a7e64de5a4f325ab7180df6d2Paul Duffin * 21a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin */ 22a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 23a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#define _XOPEN_SOURCE 600 24a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 25a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#include <pthread.h> 26a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#include <stdio.h> 27a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#include <unistd.h> 28a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#include "posixtest.h" 29a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 30a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#define THREAD_NUM 5 31a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin#define LOOPS 4 32a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 33a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffinvoid *f1(void *parm); 34a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 35a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffinpthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 36a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffinint value; /* value protected by mutex */ 37a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 38a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffinint main(void) 39a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin{ 40a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin int i, rc; 41a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin pthread_attr_t pta; 42a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin pthread_t threads[THREAD_NUM]; 43a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin //pthread_t self = pthread_self(); 44a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 45a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin pthread_attr_init(&pta); 46a805e0c533932dc3e7d640c12f3e6c949ddfdd20Paul Duffin 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 73void *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