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_lock(pthread_spinlock_t *lock) 8 * 9 * The function shall lock the spin lock referenced by lock. The calling thread 10 * shall acquire the lock if it is not held by another thread. Otherwise, the 11 * thread shall spin (that is, shall not return from the pthread_spin_lock()) 12 * until the lock becomes available. 13 * 14 * Steps: 15 * 1. Initialize a pthread_spinlock_t object 'spinlock' with 16 * pthread_spin_init() 17 * 2. Main thread lock 'spinlock', should get the lock 18 * 3. Create a child thread. The thread lock 'spinlock', should spin. 19 * 4. Main thread unlock 'spinlock' 20 * 5. Child thread should get 'spinlock' 21 */ 22 23 #define _XOPEN_SOURCE 600 24 #include <pthread.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include <signal.h> 29 #include "posixtest.h" 30 31 static pthread_spinlock_t spinlock; 32 static volatile int thread_state; 33 34 #define NOT_CREATED_THREAD 1 35 #define ENTERED_THREAD 2 36 #define EXITING_THREAD 3 37 38 static void *fn_chld(void *arg) 39 { 40 int rc = 0; 41 thread_state = ENTERED_THREAD; 42 43 (void) arg; 44 45 /* Lock the spinlock */ 46 printf("thread: attempt spin lock\n"); 47 rc = pthread_spin_lock(&spinlock); 48 if (rc != 0) { 49 printf 50 ("Test FAILED: child failed to get spin lock,error code:%d\n", 51 rc); 52 exit(PTS_FAIL); 53 } 54 printf("thread: acquired spin lock\n"); 55 56 /* Just some time between locking and unlocking */ 57 sleep(1); 58 59 /* Unlock the spin lock */ 60 printf("thread: unlock spin lock\n"); 61 if (pthread_spin_unlock(&spinlock)) { 62 printf("child: Error at pthread_spin_unlock()\n"); 63 exit(PTS_UNRESOLVED); 64 } 65 66 thread_state = EXITING_THREAD; 67 pthread_exit(0); 68 return NULL; 69 } 70 71 int main(void) 72 { 73 int cnt = 0; 74 75 pthread_t child_thread; 76 77 /* Initialize spinlock */ 78 if (pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE) != 0) { 79 printf("main: Error at pthread_spin_init()\n"); 80 return PTS_UNRESOLVED; 81 } 82 83 printf("main: attempt spin lock\n"); 84 85 /* We should get the lock */ 86 if (pthread_spin_lock(&spinlock) != 0) { 87 printf 88 ("Test FAILED: main cannot get spin lock when no one owns the lock\n"); 89 return PTS_FAIL; 90 } 91 printf("main: acquired spin lock\n"); 92 93 /* Initialize thread state */ 94 thread_state = NOT_CREATED_THREAD; 95 96 /* Create thread */ 97 printf("main: create thread\n"); 98 if (pthread_create(&child_thread, NULL, fn_chld, NULL) != 0) { 99 printf("main: Error creating child thread\n"); 100 return PTS_UNRESOLVED; 101 } 102 103 cnt = 0; 104 /* Expect the child thread to spin on spin lock. Wait for 3 seconds. */ 105 do { 106 sleep(1); 107 } while (thread_state != EXITING_THREAD && cnt++ < 3); 108 109 if (thread_state == EXITING_THREAD) { 110 printf 111 ("Test FAILED: child thread did not spin on spin lock when other thread holds the lock\n"); 112 return PTS_FAIL; 113 } else if (thread_state != ENTERED_THREAD) { 114 printf("main: Unexpected thread state %d\n", thread_state); 115 return PTS_UNRESOLVED; 116 } 117 118 printf("main: unlock spin lock\n"); 119 if (pthread_spin_unlock(&spinlock) != 0) { 120 printf("main: Error at pthread_spin_unlock()\n"); 121 return PTS_UNRESOLVED; 122 } 123 124 /* We expected the child get the spin lock and exit */ 125 cnt = 0; 126 do { 127 sleep(1); 128 } while (thread_state != EXITING_THREAD && cnt++ < 3); 129 130 if (thread_state == ENTERED_THREAD) { 131 printf("Test FAILED: child thread did not get spin lock\n"); 132 return PTS_FAIL; 133 } else if (thread_state != EXITING_THREAD) { 134 printf("main: Unexpected thread state %d\n", thread_state); 135 return PTS_UNRESOLVED; 136 } 137 138 /* Wait for thread to finish execution */ 139 if (pthread_join(child_thread, NULL) != 0) { 140 printf("main: Error at pthread_join()\n"); 141 return PTS_UNRESOLVED; 142 } 143 144 /* Destroy the spinlock */ 145 if (pthread_spin_destroy(&spinlock) != 0) { 146 printf("Error at pthread_spin_destroy()"); 147 return PTS_UNRESOLVED; 148 } 149 150 printf("Test PASSED\n"); 151 return PTS_PASS; 152 } 153