blob: 0e4a40e57b64323f5317e87af442f553a88c6dfc [file] [log] [blame]
/*
* Copyright (c) 2002, Intel Corporation. All rights reserved.
* Created by: bing.wei.liu REMOVE-THIS AT intel DOT com
* This file is licensed under the GPL license. For the full content
* of this license, see the COPYING file at the top level of this
* source tree.
* Test that pthread_mutex_lock()
* shall lock the mutex object referenced by 'mutex'. If the mutex is
* already locked, the calling thread shall block until the mutex becomes
* available. This operation shall return with the mutex object referenced
* by 'mutex' in the locked state with the calling thread as its owner.
* Steps:
* -- Initialize a mutex to protect a global variable 'value'
* -- Create N threads. Each is looped M times to acquire the mutex,
* increase the value, and then release the mutex.
* -- Check if the value has increased properly (M*N); a broken mutex
* implementation may cause lost augments.
*
*/
#define _XOPEN_SOURCE 600
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "posixtest.h"
#define THREAD_NUM 5
#define LOOPS 4
void *f1(void *parm);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int value; /* value protected by mutex */
int main()
{
int i, rc;
pthread_attr_t pta;
pthread_t threads[THREAD_NUM];
//pthread_t self = pthread_self();
pthread_attr_init(&pta);
pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE);
/* Create threads */
fprintf(stderr,"Creating %d threads\n", THREAD_NUM);
for (i=0; i<THREAD_NUM; ++i)
rc = pthread_create(&threads[i], &pta, f1, NULL);
/* Wait to join all threads */
for (i=0; i<THREAD_NUM; ++i)
pthread_join(threads[i], NULL);
pthread_attr_destroy(&pta);
pthread_mutex_destroy(&mutex);
/* Check if the final value is as expected */
if (value != (THREAD_NUM) * LOOPS) {
fprintf(stderr,"Using %d threads and each loops %d times\n", THREAD_NUM, LOOPS);
fprintf(stderr,"Final value must be %d instead of %d\n", (THREAD_NUM)*LOOPS, value);
printf("Test FAILED\n");
return PTS_FAIL;
}
printf("Test PASSED\n");
return PTS_PASS;
}
void *f1(void *parm)
{
int i, tmp;
int rc = 0;
pthread_t self = pthread_self();
/* Loopd M times to acquire the mutex, increase the value,
and then release the mutex. */
for (i=0; i<LOOPS; ++i) {
rc = pthread_mutex_lock(&mutex);
if (rc!=0) {
fprintf(stderr,"Error on pthread_mutex_lock(), rc=%d\n", rc);
return (void*)(PTS_FAIL);
}
tmp = value;
tmp = tmp+1;
fprintf(stderr,"Thread(0x%p) holds the mutex\n",(void*)self);
usleep(1000); /* delay the increasement operation */
value = tmp;
rc = pthread_mutex_unlock(&mutex);
if (rc!=0) {
fprintf(stderr,"Error on pthread_mutex_unlock(), rc=%d\n", rc);
return (void*)(PTS_UNRESOLVED);
}
sleep(1);
}
pthread_exit(0);
return (void*)(0);
}