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