1 /*-------------------------------------------------------------------------
2  * drawElements Thread Library
3  * ---------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Unix implementation of semaphore using named semaphores.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "deSemaphore.h"
25 
26 #if (DE_OS == DE_OS_IOS || DE_OS == DE_OS_OSX)
27 
28 #include "deMemory.h"
29 #include "deString.h"
30 
31 #include <semaphore.h>
32 #include <unistd.h>
33 
34 typedef struct NamedSemaphore_s
35 {
36 	sem_t*	semaphore;
37 } NamedSemaphore;
38 
NamedSemaphore_getName(const NamedSemaphore * sem,char * buf,int bufSize)39 static void NamedSemaphore_getName (const NamedSemaphore* sem, char* buf, int bufSize)
40 {
41 	deSprintf(buf, bufSize, "/desem-%d-%p", getpid(), (void*)sem);
42 }
43 
44 DE_STATIC_ASSERT(sizeof(deSemaphore) >= sizeof(NamedSemaphore*));
45 
deSemaphore_create(int initialValue,const deSemaphoreAttributes * attributes)46 deSemaphore deSemaphore_create (int initialValue, const deSemaphoreAttributes* attributes)
47 {
48 	NamedSemaphore*	sem		= (NamedSemaphore*)deCalloc(sizeof(NamedSemaphore));
49 	char			name[128];
50 	deUint32		mode	= 0700;
51 
52 	DE_UNREF(attributes);
53 
54 	if (!sem)
55 		return 0;
56 
57 	NamedSemaphore_getName(sem, name, DE_LENGTH_OF_ARRAY(name));
58 
59 	sem->semaphore = sem_open(name, O_CREAT|O_EXCL, mode, initialValue);
60 
61 	if (sem->semaphore == SEM_FAILED)
62 	{
63 		deFree(sem);
64 		return 0;
65 	}
66 
67 	return (deSemaphore)sem;
68 }
69 
deSemaphore_destroy(deSemaphore semaphore)70 void deSemaphore_destroy (deSemaphore semaphore)
71 {
72 	NamedSemaphore* sem			= (NamedSemaphore*)semaphore;
73 	char			name[128];
74 	int				res;
75 
76 	NamedSemaphore_getName(sem, name, DE_LENGTH_OF_ARRAY(name));
77 
78 	res = sem_close(sem->semaphore);
79 	DE_ASSERT(res == 0);
80 	res = sem_unlink(name);
81 	DE_ASSERT(res == 0);
82 	DE_UNREF(res);
83 	deFree(sem);
84 }
85 
deSemaphore_increment(deSemaphore semaphore)86 void deSemaphore_increment (deSemaphore semaphore)
87 {
88 	sem_t*	sem		= ((NamedSemaphore*)semaphore)->semaphore;
89 	int		res		= sem_post(sem);
90 	DE_ASSERT(res == 0);
91 	DE_UNREF(res);
92 }
93 
deSemaphore_decrement(deSemaphore semaphore)94 void deSemaphore_decrement (deSemaphore semaphore)
95 {
96 	sem_t*	sem		= ((NamedSemaphore*)semaphore)->semaphore;
97 	int		res		= sem_wait(sem);
98 	DE_ASSERT(res == 0);
99 	DE_UNREF(res);
100 }
101 
deSemaphore_tryDecrement(deSemaphore semaphore)102 deBool deSemaphore_tryDecrement (deSemaphore semaphore)
103 {
104 	sem_t* sem = ((NamedSemaphore*)semaphore)->semaphore;
105 	return (sem_trywait(sem) == 0);
106 }
107 
108 #endif /* DE_OS */
109