fat: Greatly simplify and clean up dosfs_get_file_map().
[haiku.git] / src / build / libroot / sem.cpp
blob0e2d0c9ef032a322dbc0bdcd0a30b502ad867732
2 #include <BeOSBuildCompatibility.h>
4 #include <stdlib.h>
5 #include <string.h>
7 #include <OS.h>
8 #include <SupportDefs.h>
10 // We assume that everything is single-threaded, so we don't need real
11 // semaphores. Simple fakes are sufficient.
13 struct semaphore {
14 char* name;
15 int32 count;
16 bool inUse;
19 static const int kSemaphoreCount = 40960;
20 static semaphore sSemaphores[kSemaphoreCount];
23 static bool
24 check_sem(sem_id id)
26 if (id < 0 || id >= kSemaphoreCount)
27 return false;
28 return sSemaphores[id].inUse;
31 // create_sem
32 sem_id
33 create_sem(int32 count, const char *name)
35 for (int i = 0; i < kSemaphoreCount; i++) {
36 semaphore &sem = sSemaphores[i];
37 if (!sem.inUse) {
38 sem.name = strdup(name ? name : "unnamed sem");
39 if (!sem.name)
40 return B_NO_MEMORY;
42 sem.inUse = true;
43 sem.count = count;
45 return i;
49 return B_NO_MORE_SEMS;
52 // delete_sem
53 status_t
54 delete_sem(sem_id id)
56 if (!check_sem(id))
57 return B_BAD_SEM_ID;
59 sSemaphores[id].inUse = false;
60 free(sSemaphores[id].name);
61 sSemaphores[id].name = NULL;
63 return B_OK;
66 // acquire_sem
67 status_t
68 acquire_sem(sem_id id)
70 return acquire_sem_etc(id, 1, 0, 0);
73 // acquire_sem_etc
74 status_t
75 acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
77 if (!check_sem(id))
78 return B_BAD_SEM_ID;
80 if (count <= 0)
81 return B_BAD_VALUE;
83 semaphore &sem = sSemaphores[id];
84 if (sem.count >= count) {
85 sem.count -= count;
86 return B_OK;
89 if (timeout < 0)
90 timeout = 0;
92 bool noTimeout = false;
93 if (flags & B_RELATIVE_TIMEOUT) {
94 // relative timeout: get the absolute time when to time out
96 // special case: on timeout == 0 we return B_WOULD_BLOCK
97 if (timeout == 0)
98 return B_WOULD_BLOCK;
100 bigtime_t currentTime = system_time();
101 if (timeout > B_INFINITE_TIMEOUT || currentTime >= B_INFINITE_TIMEOUT - timeout) {
102 noTimeout = true;
103 } else {
104 timeout += currentTime;
107 } else if (flags & B_ABSOLUTE_TIMEOUT) {
108 // absolute timeout
109 } else {
110 // no timeout given
111 noTimeout = true;
114 // no timeout?
115 if (noTimeout) {
116 debugger("Would block on a semaphore without timeout in a "
117 "single-threaded context!");
118 return B_ERROR;
121 // wait for the time out time
122 status_t error = snooze_until(timeout, B_SYSTEM_TIMEBASE);
123 if (error != B_OK)
124 return error;
126 return B_TIMED_OUT;
129 // release_sem
130 status_t
131 release_sem(sem_id id)
133 return release_sem_etc(id, 1, 0);
136 // release_sem_etc
137 status_t
138 release_sem_etc(sem_id id, int32 count, uint32 flags)
140 if (!check_sem(id))
141 return B_BAD_SEM_ID;
143 if (count <= 0)
144 return B_BAD_VALUE;
146 semaphore &sem = sSemaphores[id];
147 sem.count += count;
149 return B_OK;
152 // get_sem_count
153 status_t
154 get_sem_count(sem_id id, int32 *threadCount)
156 if (!check_sem(id))
157 return B_BAD_SEM_ID;
159 if (!threadCount)
160 return B_BAD_VALUE;
162 *threadCount = sSemaphores[id].count;
163 return B_OK;
166 // set_sem_owner
167 status_t
168 set_sem_owner(sem_id id, team_id team)
170 if (!check_sem(id))
171 return B_BAD_SEM_ID;
173 return B_OK;
176 // _get_sem_info
177 status_t
178 _get_sem_info(sem_id id, struct sem_info *info, size_t infoSize)
180 if (!check_sem(id))
181 return B_BAD_SEM_ID;
183 if (!info)
184 return B_BAD_VALUE;
186 info->sem = id;
187 info->team = 1;
188 strlcpy(info->name, sSemaphores[id].name, sizeof(info->name));
189 info->count = sSemaphores[id].count;
190 info->latest_holder = -1;
192 return B_OK;
195 // _get_next_sem_info
196 status_t
197 _get_next_sem_info(team_id team, int32 *cookie, struct sem_info *info,
198 size_t infoSize)
200 if (team < 0 || team > 2)
201 return B_BAD_TEAM_ID;
203 for (int i = *cookie; i < kSemaphoreCount; i++) {
204 if (sSemaphores[i].inUse) {
205 *cookie = i + 1;
206 return _get_sem_info(i, info, infoSize);
210 return B_ENTRY_NOT_FOUND;