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