Home | History | Annotate | Download | only in pthread_mutex_unlock
      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