1/*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * This file is licensed under the GPL license.  For the full content
4 * of this license, see the COPYING file at the top level of this
5 * source tree.
6 *
7 * Test pthread_spin_unlock(pthread_spinlock_t *lock)
8 *
9 * The function shall release the spin lock referenced by 'lock' which
10 * was locked via the pthread_spin_lock() or pthread_spin_trylock().
11 *
12 * Steps:
13 * 1.  Initialize a pthread_spinlock_t object 'spinlock' with
14 *     pthread_spin_init()
15 * 2.  Main thread lock 'spinlock' with pthread_spin_lock(),  should get the lock
16 * 3.  Main thread unlock 'spinlock'
17 * 4.  Create a child thread. The thread try to lock 'spinlock', with
18 *     pthread_spin_trylock(), should get the lock.
19 * 5.  Child thread unlock
20 * 6.  Main thread lock 'spinlock', using pthread_spin_trylock(), should get
21 *     lock
22 * 7.  Main thread unlock 'spinlock'
23 */
24
25#define _XOPEN_SOURCE 600
26#include <pthread.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <signal.h>
31#include "posixtest.h"
32
33static pthread_spinlock_t spinlock;
34volatile static int thread_state;
35
36#define NOT_CREATED_THREAD 1
37#define ENTERED_THREAD 2
38#define EXITING_THREAD 3
39
40static void* fn_chld(void *arg)
41{
42	int rc = 0;
43	thread_state = ENTERED_THREAD;
44
45	printf("thread: attempt trylock\n");
46	rc = pthread_spin_trylock(&spinlock);
47	if(rc != 0)
48	{
49		printf("Test FAILED: thread failed to get spin lock,"
50			"Error code:%d\n" , rc);
51		exit(PTS_FAIL);
52	}
53	printf("thread: acquired spin lock\n");
54
55	printf("thread: unlock spin lock\n");
56	if(pthread_spin_unlock(&spinlock))
57	{
58		printf("thread: Error at pthread_spin_unlock()\n");
59		exit(PTS_FAIL);
60	}
61
62	thread_state = EXITING_THREAD;
63	pthread_exit(0);
64	return NULL;
65}
66
67int main()
68{
69	int rc;
70
71	pthread_t child_thread;
72
73	if(pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE) != 0)
74	{
75		printf("main: Error at pthread_spin_init()\n");
76		return PTS_UNRESOLVED;
77	}
78
79	printf("main: attempt spin lock\n");
80
81	/* We should get the lock */
82	if(pthread_spin_lock(&spinlock) != 0)
83	{
84		printf("main: cannot get spin lock when no one owns the lock\n");
85		return PTS_UNRESOLVED;
86	}
87	printf("main: acquired spin lock\n");
88
89	printf("main: unlock spin lock\n");
90	rc = pthread_spin_unlock(&spinlock);
91	if(rc != 0)
92	{
93		printf("main: Error at pthread_spin_unlock()\n");
94		return PTS_FAIL;
95	}
96
97	thread_state = NOT_CREATED_THREAD;
98	printf("main: create thread\n");
99	if(pthread_create(&child_thread, NULL, fn_chld, NULL) != 0)
100	{
101		printf("main: Error creating thread\n");
102		return PTS_UNRESOLVED;
103	}
104
105	/* Wait for thread to end execution */
106	if(pthread_join(child_thread, NULL) != 0)
107	{
108		printf("main: Error at pthread_join()\n");
109		return PTS_UNRESOLVED;
110	}
111
112	printf("main: try to lock again when thread unlocked\n");
113	if(pthread_spin_trylock(&spinlock) != 0)
114	{
115		printf("main: Should get spin lock\n");
116		return PTS_FAIL;
117	}
118
119	printf("main: acquired spin lock\n");
120	printf("main: unlock spin lock\n");
121	if(pthread_spin_unlock(&spinlock) != 0)
122	{
123		printf("Test FAILED: main: Error at pthread_spin_unlock()\n");
124		return PTS_FAIL;
125	}
126
127	if(pthread_spin_destroy(&spinlock) != 0)
128	{
129		printf("Error at pthread_spin_destroy()");
130		return PTS_UNRESOLVED;
131	}
132
133	printf("Test PASSED\n");
134	return PTS_PASS;
135}
136