1/*
2 *  sema_tests.c
3 *  xnu_quick_test
4 *
5 *  Created by Jerry Cottingham on 6/2/2005.
6 *  Copyright 2005 Apple Computer Inc. All rights reserved.
7 *
8 */
9
10#include "tests.h"
11#include <sys/sem.h>
12#include <semaphore.h>
13
14/*  **************************************************************************************************************
15 *	Test semctl, semget, semop system calls.
16 *  **************************************************************************************************************
17 */
18int sema_tests( void * the_argp )
19{
20	int				my_err, i;
21	int				my_sem_id = -1;
22 	union semun		my_sem_union;
23	struct sembuf	my_sembuf;
24
25	srand( (unsigned int)getpid() );
26	my_sem_id = semget( (key_t)1234, 1, (0666 | IPC_CREAT) );
27	if ( my_sem_id == -1 ) {
28		printf( "semget failed with error %d - \"%s\" \n", errno, strerror( errno) );
29		goto test_failed_exit;
30	}
31
32 	my_sem_union.val = 1;
33	my_err = semctl( my_sem_id, 0, SETVAL, my_sem_union );
34	if ( my_sem_id == -1 ) {
35		printf( "semget failed with error %d - \"%s\" \n", errno, strerror( errno) );
36		goto test_failed_exit;
37	}
38
39	/* verify semop failure for bad nsop values */
40	my_err = semop( my_sem_id, &my_sembuf, 10000);
41	if (my_err != -1 || errno != E2BIG) {
42		printf( "semop did not fail with E2BIG - instead %d - \"%s\" \n", errno, strerror( errno) );
43		goto test_failed_exit;
44
45	}
46
47	for ( i = 0; i < 10000; i++ ) {
48		my_sembuf.sem_num = 0;
49		my_sembuf.sem_op  = -1;
50		my_sembuf.sem_flg = SEM_UNDO;
51
52		my_err = semop( my_sem_id, &my_sembuf, 1 );
53		if ( my_err == -1 ) {
54			printf( "semop failed with error %d - \"%s\" \n", errno, strerror( errno) );
55			goto test_failed_exit;
56		}
57
58		my_err = semctl( my_sem_id, 0, GETVAL, 0 );
59		if ( my_err == -1 ) {
60			printf( "semctl failed with error %d - \"%s\" \n", errno, strerror( errno) );
61			goto test_failed_exit;
62		}
63		if ( my_err != 0 ) {
64			printf( "semctl(getval) returned %d. it should be 0 (locked) here \n", my_err );
65			goto test_failed_exit;
66        }
67
68		my_sembuf.sem_num = 0;
69		my_sembuf.sem_op  = 1;
70		my_sembuf.sem_flg = SEM_UNDO;
71
72		my_err = semop( my_sem_id, &my_sembuf, 1 );
73		if ( my_err == -1 ) {
74			printf( "semop failed with error %d - \"%s\" \n", errno, strerror( errno) );
75			goto test_failed_exit;
76		}
77	}
78
79	my_err = semctl( my_sem_id, 0, IPC_RMID, my_sem_union );
80	if ( my_err == -1 ) {
81		printf( "semctl (IPC_RMID) failed with error %d - \"%s\" \n", errno, strerror( errno) );
82		goto test_failed_exit;
83	}
84	my_sem_id = -1;
85	my_err = 0;
86	goto test_passed_exit;
87
88test_failed_exit:
89	my_err = -1;
90
91test_passed_exit:
92	if ( my_sem_id != -1 ) {
93		semctl( my_sem_id, 0, IPC_RMID, my_sem_union );
94	}
95	return( my_err );
96}
97
98
99/*  **************************************************************************************************************
100 *	Test sem_close, sem_open, sem_post, sem_trywait, sem_unlink, sem_wait system calls.
101 *  **************************************************************************************************************
102 */
103int sema2_tests( void * the_argp )
104{
105	int				my_err;
106	sem_t *			my_sem_t = (sem_t *)SEM_FAILED;
107	char			my_sema_name[ 64 ];
108
109	/* get a semaphore (initialized as locked) */
110	sprintf( &my_sema_name[0], "sema_testing_%d", getpid( ) );
111	my_sem_t = sem_open( &my_sema_name[0], (O_CREAT | O_EXCL), (S_IRUSR | S_IWUSR), 0 );
112	if ( my_sem_t == (sem_t*)SEM_FAILED ) {
113		printf( "sem_open failed with error %d - \"%s\" \n", errno, strerror( errno) );
114		goto test_failed_exit;
115	}
116
117	/* get the lock - should return EAGAIN (EWOULDBLOCK) */
118	my_err = sem_trywait( my_sem_t );
119	if ( my_err == -1 ) {
120		my_err = errno;
121		if ( my_err != EAGAIN ) {
122			printf( "sem_trywait failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
123			goto test_failed_exit;
124		}
125	}
126
127	/* unlock our semaphore */
128	my_err = sem_post( my_sem_t );
129	if ( my_err == -1 ) {
130		printf( "sem_post failed with error %d - \"%s\" \n", errno, strerror( errno) );
131		goto test_failed_exit;
132	}
133
134	/* get the lock again */
135	my_err = sem_wait( my_sem_t );
136	if ( my_err == -1 ) {
137		printf( "sem_wait failed with error %d - \"%s\" \n", errno, strerror( errno) );
138		goto test_failed_exit;
139	}
140
141	my_err = sem_unlink( &my_sema_name[0] );
142	if ( my_err == -1 ) {
143		printf( "sem_unlink failed with error %d - \"%s\" \n", errno, strerror( errno) );
144		goto test_failed_exit;
145	}
146
147	my_err = sem_close( my_sem_t );
148	if ( my_err == -1 ) {
149		printf( "sem_close failed with error %d - \"%s\" \n", errno, strerror( errno) );
150		goto test_failed_exit;
151	}
152	my_sem_t = (sem_t *)SEM_FAILED;
153
154	my_err = 0;
155	goto test_passed_exit;
156
157test_failed_exit:
158	my_err = -1;
159
160test_passed_exit:
161	if ( my_sem_t != (sem_t *)SEM_FAILED ) {
162		sem_close( my_sem_t );
163	}
164	return( my_err );
165}
166