1
2/*
3 *  Copyright (c) 2003, Intel Corporation. All rights reserved.
4 *  Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
5 *  This file is licensed under the GPL license.  For the full content
6 *  of this license, see the COPYING file at the top level of this
7 *  source tree.
8 */
9
10/* In x-mode
11 * There are several threads that share a mutex, When the owner of mutex is
12 * dead, a waiter locks the mutex and will get EOWNERDEAD. In
13 * PTHREAD_MUTEX_ROBUST_NP Mode, if the owner can't recover it to
14 * heathy state(not_recoverable state), then calling
15 * pthread_mutex_setconsistency_np will change the mutex state to
16 * ENOTRECOVERABLE.
17 */
18
19#include <pthread.h>
20#include <stdio.h>
21#include <unistd.h>
22#include <string.h>
23#include <stdlib.h>
24#include "test.h"
25
26#define THREAD_NUM		2
27
28pthread_mutex_t	mutex;
29
30void *thread_1(void *arg)
31{
32 	pthread_mutex_lock(&mutex);
33	DPRINTF(stdout,"Thread 1 locked the mutex \n");
34	pthread_exit(NULL);
35	return NULL;
36}
37void *thread_2(void *arg)
38{
39	int state;
40	int rc;
41	pthread_t self = pthread_self();
42        int policy = SCHED_FIFO;
43	struct sched_param param;
44        memset(&param, 0, sizeof(param));
45        param.sched_priority = sched_get_priority_min(policy);
46
47        rc = pthread_setschedparam(self, policy, &param);
48        if (rc != 0) {
49             EPRINTF("UNRESOLVED: pthread_setschedparam %d %s",
50		     rc, strerror(rc));
51	     exit(UNRESOLVED);
52        }
53
54	rc = pthread_mutex_lock(&mutex);
55	if (rc != EOWNERDEAD)  {
56		EPRINTF("FAIL:pthread_mutex_lock didn't return EOWNERDEAD \n");
57		exit(FAIL);
58	}
59	DPRINTF(stdout,"Thread 2 lock the mutex and return EOWNERDEAD \n");
60
61	state = 1;
62	if (pthread_mutex_setconsistency_np(&mutex, state) == 0) {
63		pthread_mutex_unlock(&mutex);
64		rc = pthread_mutex_lock(&mutex);
65		if (rc != ENOTRECOVERABLE) {
66			EPRINTF("FAIL:The mutex does not set to "
67				"ENOTRECOVERABLE when called "
68				"pthread_mutex_setconsistency_np successfully "
69				"in x-mode");
70			pthread_mutex_unlock(&mutex);
71			exit(FAIL);
72		}
73		else {
74			DPRINTF(stdout,"PASS: The mutex is set to ENOTRECOVERABLE if "
75				"successfully called "
76				"pthreadmutex_setconsistency_np in x-mode\n");
77			pthread_mutex_unlock(&mutex);
78		}
79	}
80	else {
81		pthread_mutex_unlock(&mutex);
82		rc = pthread_mutex_lock(&mutex);
83		if (rc != EOWNERDEAD) {
84			EPRINTF("FAIL:The mutex shall not set to "
85				"ENOTRECOVERABLE automaticly after unlock "
86				"if can't recover it to normal state in x-mode");
87			pthread_mutex_unlock(&mutex);
88			exit(FAIL);
89		}
90		else {
91			DPRINTF(stdout,"PASS: The mutex remains in "
92				"EOWNERDEAD state if the calling to "
93				"pthread_mutex_consistency_np fails "
94				"(Why fails?) in x-mode \n");
95			pthread_mutex_unlock(&mutex);
96		}
97	}
98	pthread_exit(NULL);
99	return NULL;
100}
101
102int main()
103{
104	pthread_mutexattr_t attr;
105	pthread_t threads[THREAD_NUM];
106	pthread_attr_t threadattr;
107	int rc;
108
109	rc = pthread_mutexattr_init(&attr);
110	if (rc != 0) {
111		EPRINTF("UNRESOLVED: pthread_mutexattr_init %d %s",
112			rc, strerror(rc));
113		return UNRESOLVED;
114	}
115	rc = pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP);
116	if (rc != 0) {
117		EPRINTF("UNRESOLVED: pthread_mutexattr_setrobust_np %d %s",
118			rc, strerror(rc));
119		return UNRESOLVED;
120	}
121	rc = pthread_mutex_init(&mutex, &attr);
122	if (rc != 0) {
123		EPRINTF("UNRESOLVED: pthread_mutex_init %d %s",
124			rc, strerror(rc));
125		return UNRESOLVED;
126	}
127	rc = pthread_attr_init(&threadattr);
128	if (rc != 0) {
129		EPRINTF("UNRESOLVED: pthread_attr_init %d %s",
130			rc, strerror(rc));
131		return UNRESOLVED;
132	}
133	rc = pthread_create(&threads[0], &threadattr, thread_1, NULL);
134	if (rc != 0) {
135		EPRINTF("UNRESOLVED: pthread_create %d %s",
136			rc, strerror(rc));
137		return UNRESOLVED;
138	}
139	pthread_join(threads[0], NULL);
140	DPRINTF(stdout,"Thread 1 exit without unlock the mutex...\n ");
141
142	rc = pthread_create(&threads[1], &threadattr, thread_2, NULL);
143	if (rc != 0) {
144		EPRINTF("UNRESOLVED: pthread_create %d %s",
145			rc, strerror(rc));
146		return UNRESOLVED;
147	}
148	pthread_join(threads[1], NULL );
149	DPRINTF(stdout,"Thread 2 exit ...\n ");
150
151	DPRINTF(stdout,"PASS: Test PASSED\n");
152	return PASS;
153}
154
155