Got rid of gSemRegion as it is never really used.

Renamed all static global variables to have the 's' prefix.
acquire_sem_etc() now fails if B_RELATIVE_TIMEOUT and B_ABSOLUTE_TIMEOUT
are both set.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9854 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-11-08 13:57:40 +00:00
parent 148a8e0c57
commit 07bdb9c6ea
+105 -100
View File
@@ -1,5 +1,5 @@
/* /*
** Copyright 2002-2004, The Haiku Team. All rights reserved. ** Copyright 2002-2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the Haiku License. ** Distributed under the terms of the Haiku License.
** **
** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
@@ -55,11 +55,10 @@ struct sem_entry {
static int32 sMaxSems = 4096; static int32 sMaxSems = 4096;
static int32 sUsedSems = 0; static int32 sUsedSems = 0;
static struct sem_entry *gSems = NULL; static struct sem_entry *sSems = NULL;
static region_id gSemRegion = 0; static bool sSemsActive = false;
static bool gSemsActive = false; static struct sem_entry *sFreeSemsHead = NULL;
static struct sem_entry *gFreeSemsHead = NULL; static struct sem_entry *sFreeSemsTail = NULL;
static struct sem_entry *gFreeSemsTail = NULL;
static spinlock sem_spinlock = 0; static spinlock sem_spinlock = 0;
#define GRAB_SEM_LIST_LOCK() acquire_spinlock(&sem_spinlock) #define GRAB_SEM_LIST_LOCK() acquire_spinlock(&sem_spinlock)
@@ -83,9 +82,9 @@ dump_sem_list(int argc, char **argv)
int i; int i;
for (i = 0; i < sMaxSems; i++) { for (i = 0; i < sMaxSems; i++) {
if (gSems[i].id >= 0) if (sSems[i].id >= 0)
dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &gSems[i], gSems[i].id, dprintf("%p\tid: 0x%lx\t\tname: '%s'\n", &sSems[i], sSems[i].id,
gSems[i].u.used.name); sSems[i].u.used.name);
} }
return 0; return 0;
} }
@@ -129,20 +128,20 @@ dump_sem_info(int argc, char **argv)
return 0; return 0;
} else { } else {
unsigned slot = num % sMaxSems; unsigned slot = num % sMaxSems;
if (gSems[slot].id != (int)num) { if (sSems[slot].id != (int)num) {
dprintf("sem 0x%lx doesn't exist!\n", num); dprintf("sem 0x%lx doesn't exist!\n", num);
return 0; return 0;
} }
dump_sem(&gSems[slot]); dump_sem(&sSems[slot]);
return 0; return 0;
} }
} }
// walk through the sem list, trying to match name // walk through the sem list, trying to match name
for (i = 0; i < sMaxSems; i++) { for (i = 0; i < sMaxSems; i++) {
if (gSems[i].u.used.name != NULL if (sSems[i].u.used.name != NULL
&& strcmp(argv[1], gSems[i].u.used.name) == 0) { && strcmp(argv[1], sSems[i].u.used.name) == 0) {
dump_sem(&gSems[i]); dump_sem(&sSems[i]);
return 0; return 0;
} }
} }
@@ -163,18 +162,18 @@ dump_sem_info(int argc, char **argv)
static void static void
free_sem_slot(int slot, sem_id nextID) free_sem_slot(int slot, sem_id nextID)
{ {
struct sem_entry *sem = gSems + slot; struct sem_entry *sem = sSems + slot;
// set next_id to the next possible value; for sanity check the current ID // set next_id to the next possible value; for sanity check the current ID
if (nextID < 0) if (nextID < 0)
sem->u.unused.next_id = slot; sem->u.unused.next_id = slot;
else else
sem->u.unused.next_id = nextID; sem->u.unused.next_id = nextID;
// append the entry to the list // append the entry to the list
if (gFreeSemsTail) if (sFreeSemsTail)
gFreeSemsTail->u.unused.next = sem; sFreeSemsTail->u.unused.next = sem;
else else
gFreeSemsHead = sem; sFreeSemsHead = sem;
gFreeSemsTail = sem; sFreeSemsTail = sem;
sem->u.unused.next = NULL; sem->u.unused.next = NULL;
} }
@@ -182,19 +181,20 @@ free_sem_slot(int slot, sem_id nextID)
status_t status_t
sem_init(kernel_args *ka) sem_init(kernel_args *ka)
{ {
area_id area;
int i; int i;
TRACE(("sem_init: entry\n")); TRACE(("sem_init: entry\n"));
// create and initialize semaphore table // create and initialize semaphore table
gSemRegion = create_area("sem_table", (void **)&gSems, B_ANY_KERNEL_ADDRESS, area = create_area("sem_table", (void **)&sSems, B_ANY_KERNEL_ADDRESS,
sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
if (gSemRegion < 0) if (area < 0)
panic("unable to allocate semaphore table!\n"); panic("unable to allocate semaphore table!\n");
memset(gSems, 0, sizeof(struct sem_entry) * sMaxSems); memset(sSems, 0, sizeof(struct sem_entry) * sMaxSems);
for (i = 0; i < sMaxSems; i++) { for (i = 0; i < sMaxSems; i++) {
gSems[i].id = -1; sSems[i].id = -1;
free_sem_slot(i, i); free_sem_slot(i, i);
} }
@@ -204,7 +204,7 @@ sem_init(kernel_args *ka)
TRACE(("sem_init: exit\n")); TRACE(("sem_init: exit\n"));
gSemsActive = true; sSemsActive = true;
return 0; return 0;
} }
@@ -227,7 +227,7 @@ create_sem_etc(int32 count, const char *name, team_id owner)
char *tempName; char *tempName;
size_t nameLength; size_t nameLength;
if (gSemsActive == false || sUsedSems == sMaxSems) if (sSemsActive == false || sUsedSems == sMaxSems)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (name == NULL) if (name == NULL)
@@ -244,12 +244,12 @@ create_sem_etc(int32 count, const char *name, team_id owner)
GRAB_SEM_LIST_LOCK(); GRAB_SEM_LIST_LOCK();
// get the first slot from the free list // get the first slot from the free list
sem = gFreeSemsHead; sem = sFreeSemsHead;
if (sem) { if (sem) {
// remove it from the free list // remove it from the free list
gFreeSemsHead = sem->u.unused.next; sFreeSemsHead = sem->u.unused.next;
if (!gFreeSemsHead) if (!sFreeSemsHead)
gFreeSemsTail = NULL; sFreeSemsTail = NULL;
// init the slot // init the slot
GRAB_SEM_LOCK(*sem); GRAB_SEM_LOCK(*sem);
sem->id = sem->u.unused.next_id; sem->id = sem->u.unused.next_id;
@@ -291,7 +291,7 @@ delete_sem(sem_id id)
char *old_name; char *old_name;
struct thread_queue release_queue; struct thread_queue release_queue;
if (gSemsActive == false) if (sSemsActive == false)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (id < 0) if (id < 0)
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -299,10 +299,10 @@ delete_sem(sem_id id)
slot = id % sMaxSems; slot = id % sMaxSems;
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != id) { if (sSems[slot].id != id) {
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
TRACE(("delete_sem: invalid sem_id %ld\n", id)); TRACE(("delete_sem: invalid sem_id %ld\n", id));
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -312,7 +312,7 @@ delete_sem(sem_id id)
release_queue.head = release_queue.tail = NULL; release_queue.head = release_queue.tail = NULL;
// free any threads waiting for this semaphore // free any threads waiting for this semaphore
while ((t = thread_dequeue(&gSems[slot].u.used.q)) != NULL) { while ((t = thread_dequeue(&sSems[slot].u.used.q)) != NULL) {
t->state = B_THREAD_READY; t->state = B_THREAD_READY;
t->sem.acquire_status = B_BAD_SEM_ID; t->sem.acquire_status = B_BAD_SEM_ID;
t->sem.count = 0; t->sem.count = 0;
@@ -320,11 +320,11 @@ delete_sem(sem_id id)
released_threads++; released_threads++;
} }
gSems[slot].id = -1; sSems[slot].id = -1;
old_name = gSems[slot].u.used.name; old_name = sSems[slot].u.used.name;
gSems[slot].u.used.name = NULL; sSems[slot].u.used.name = NULL;
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
// append slot to the free list // append slot to the free list
GRAB_SEM_LIST_LOCK(); GRAB_SEM_LIST_LOCK();
@@ -366,20 +366,20 @@ sem_timeout(timer *data)
slot = args->blocked_sem_id % sMaxSems; slot = args->blocked_sem_id % sMaxSems;
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
TRACE(("sem_timeout: called on 0x%x sem %ld, tid %ld\n", data, args->blocked_sem_id, args->blocked_thread)); TRACE(("sem_timeout: called on 0x%x sem %ld, tid %ld\n", data, args->blocked_sem_id, args->blocked_thread));
if (gSems[slot].id != args->blocked_sem_id) { if (sSems[slot].id != args->blocked_sem_id) {
// this thread was not waiting on this semaphore // this thread was not waiting on this semaphore
panic("sem_timeout: thid %ld was trying to wait on sem %ld which doesn't exist!\n", panic("sem_timeout: thid %ld was trying to wait on sem %ld which doesn't exist!\n",
args->blocked_thread, args->blocked_sem_id); args->blocked_thread, args->blocked_sem_id);
} }
wakeup_queue.head = wakeup_queue.tail = NULL; wakeup_queue.head = wakeup_queue.tail = NULL;
remove_thread_from_sem(t, &gSems[slot], &wakeup_queue, B_TIMED_OUT); remove_thread_from_sem(t, &sSems[slot], &wakeup_queue, B_TIMED_OUT);
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
// put the threads in the run q here to make sure we dont deadlock in sem_interrupt_thread // put the threads in the run q here to make sure we dont deadlock in sem_interrupt_thread
@@ -408,7 +408,7 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
int state; int state;
status_t status = B_OK; status_t status = B_OK;
if (gSemsActive == false) if (sSemsActive == false)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (!kernel_startup && !are_interrupts_enabled()) if (!kernel_startup && !are_interrupts_enabled())
@@ -416,38 +416,40 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
if (id < 0) if (id < 0)
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
if (count <= 0) if (count <= 0
|| (flags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT)) == (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT)) {
return B_BAD_VALUE; return B_BAD_VALUE;
}
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != id) { if (sSems[slot].id != id) {
TRACE(("acquire_sem_etc: bad sem_id %ld\n", id)); TRACE(("acquire_sem_etc: bad sem_id %ld\n", id));
status = B_BAD_SEM_ID; status = B_BAD_SEM_ID;
goto err; goto err;
} }
if (gSems[slot].u.used.count - count < 0 && (flags & B_TIMEOUT) != 0 if (sSems[slot].u.used.count - count < 0 && (flags & B_TIMEOUT) != 0
&& timeout <= 0) { && timeout <= 0) {
// immediate timeout // immediate timeout
status = B_WOULD_BLOCK; status = B_WOULD_BLOCK;
goto err; goto err;
} }
if ((gSems[slot].u.used.count -= count) < 0) { if ((sSems[slot].u.used.count -= count) < 0) {
// we need to block // we need to block
struct thread *t = thread_get_current_thread(); struct thread *t = thread_get_current_thread();
timer timeout_timer; // stick it on the stack, since we may be blocking here timer timeout_timer; // stick it on the stack, since we may be blocking here
struct sem_timeout_args args; struct sem_timeout_args args;
TRACE_BLOCK(("acquire_sem_etc(id = %ld): block name = %s, thread = %p," TRACE_BLOCK(("acquire_sem_etc(id = %ld): block name = %s, thread = %p,"
" name = %s\n", id, gSems[slot].u.used.name, t, t->name)); " name = %s\n", id, sSems[slot].u.used.name, t, t->name));
// do a quick check to see if the thread has any pending signals // do a quick check to see if the thread has any pending signals
// this should catch most of the cases where the thread had a signal // this should catch most of the cases where the thread had a signal
if ((flags & B_CAN_INTERRUPT) && t->sig_pending) { if ((flags & B_CAN_INTERRUPT) && t->sig_pending) {
gSems[slot].u.used.count += count; sSems[slot].u.used.count += count;
status = B_INTERRUPTED; status = B_INTERRUPTED;
goto err; goto err;
} }
@@ -456,10 +458,10 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
t->sem.flags = flags; t->sem.flags = flags;
t->sem.blocking = id; t->sem.blocking = id;
t->sem.acquire_count = count; t->sem.acquire_count = count;
t->sem.count = min(-gSems[slot].u.used.count, count); t->sem.count = min(-sSems[slot].u.used.count, count);
// store the count we need to restore upon release // store the count we need to restore upon release
t->sem.acquire_status = B_NO_ERROR; t->sem.acquire_status = B_NO_ERROR;
thread_enqueue(t, &gSems[slot].u.used.q); thread_enqueue(t, &sSems[slot].u.used.q);
if ((flags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT)) != 0) { if ((flags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT)) != 0) {
TRACE(("sem_acquire_etc: setting timeout sem for %Ld usecs, semid %d, tid %d\n", TRACE(("sem_acquire_etc: setting timeout sem for %Ld usecs, semid %d, tid %d\n",
@@ -477,7 +479,7 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
B_ONE_SHOT_RELATIVE_TIMER : B_ONE_SHOT_ABSOLUTE_TIMER); B_ONE_SHOT_RELATIVE_TIMER : B_ONE_SHOT_ABSOLUTE_TIMER);
} }
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
GRAB_THREAD_LOCK(); GRAB_THREAD_LOCK();
// check again to see if a signal is pending. // check again to see if a signal is pending.
// it may have been delivered while setting up the sem, though it's pretty unlikely // it may have been delivered while setting up the sem, though it's pretty unlikely
@@ -488,11 +490,11 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
// here, since the threadlock is held. The previous check would have found most // here, since the threadlock is held. The previous check would have found most
// instances, but there was a race, so we have to handle it. It'll be more messy... // instances, but there was a race, so we have to handle it. It'll be more messy...
wakeup_queue.head = wakeup_queue.tail = NULL; wakeup_queue.head = wakeup_queue.tail = NULL;
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id == id) { if (sSems[slot].id == id) {
remove_thread_from_sem(t, &gSems[slot], &wakeup_queue, EINTR); remove_thread_from_sem(t, &sSems[slot], &wakeup_queue, EINTR);
} }
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
while ((t = thread_dequeue(&wakeup_queue)) != NULL) { while ((t = thread_dequeue(&wakeup_queue)) != NULL) {
scheduler_enqueue_in_run_queue(t); scheduler_enqueue_in_run_queue(t);
} }
@@ -512,13 +514,13 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
restore_interrupts(state); restore_interrupts(state);
TRACE_BLOCK(("acquire_sem_etc(id = %ld): exit block name = %s, " TRACE_BLOCK(("acquire_sem_etc(id = %ld): exit block name = %s, "
"thread = %p (%s)\n", id, gSems[slot].u.used.name, t, "thread = %p (%s)\n", id, sSems[slot].u.used.name, t,
t->name)); t->name));
return t->sem.acquire_status; return t->sem.acquire_status;
} }
err: err:
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
return status; return status;
@@ -540,7 +542,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
cpu_status state; cpu_status state;
status_t status = B_OK; status_t status = B_OK;
if (gSemsActive == false) if (sSemsActive == false)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (id < 0) if (id < 0)
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -548,9 +550,9 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
return B_BAD_VALUE; return B_BAD_VALUE;
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != id) { if (sSems[slot].id != id) {
TRACE(("sem_release_etc: invalid sem_id %ld\n", id)); TRACE(("sem_release_etc: invalid sem_id %ld\n", id));
status = B_BAD_SEM_ID; status = B_BAD_SEM_ID;
goto err; goto err;
@@ -563,7 +565,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
releaseQueue.head = releaseQueue.tail = NULL; releaseQueue.head = releaseQueue.tail = NULL;
if (flags & B_RELEASE_ALL) { if (flags & B_RELEASE_ALL) {
count = -gSems[slot].u.used.count; count = -sSems[slot].u.used.count;
// is there anything to do for us at all? // is there anything to do for us at all?
if (count == 0) if (count == 0)
@@ -572,14 +574,14 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
while (count > 0) { while (count > 0) {
int delta = count; int delta = count;
if (gSems[slot].u.used.count < 0) { if (sSems[slot].u.used.count < 0) {
struct thread *thread = thread_lookat_queue(&gSems[slot].u.used.q); struct thread *thread = thread_lookat_queue(&sSems[slot].u.used.q);
delta = min(count, thread->sem.count); delta = min(count, thread->sem.count);
thread->sem.count -= delta; thread->sem.count -= delta;
if (thread->sem.count <= 0) { if (thread->sem.count <= 0) {
// release this thread // release this thread
thread = thread_dequeue(&gSems[slot].u.used.q); thread = thread_dequeue(&sSems[slot].u.used.q);
thread_enqueue(thread, &releaseQueue); thread_enqueue(thread, &releaseQueue);
thread->state = B_THREAD_READY; thread->state = B_THREAD_READY;
thread->sem.count = 0; thread->sem.count = 0;
@@ -587,10 +589,10 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
} else if (flags & B_RELEASE_IF_WAITING_ONLY) } else if (flags & B_RELEASE_IF_WAITING_ONLY)
break; break;
gSems[slot].u.used.count += delta; sSems[slot].u.used.count += delta;
count -= delta; count -= delta;
} }
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
// pull off any items in the release queue and put them in the run queue // pull off any items in the release queue and put them in the run queue
if (releaseQueue.head != NULL) { if (releaseQueue.head != NULL) {
@@ -614,7 +616,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
goto outnolock; goto outnolock;
err: err:
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
outnolock: outnolock:
restore_interrupts(state); restore_interrupts(state);
@@ -628,7 +630,7 @@ get_sem_count(sem_id id, int32 *thread_count)
int slot; int slot;
int state; int state;
if (gSemsActive == false) if (sSemsActive == false)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (id < 0) if (id < 0)
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -638,18 +640,18 @@ get_sem_count(sem_id id, int32 *thread_count)
slot = id % sMaxSems; slot = id % sMaxSems;
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != id) { if (sSems[slot].id != id) {
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
TRACE(("sem_get_count: invalid sem_id %ld\n", id)); TRACE(("sem_get_count: invalid sem_id %ld\n", id));
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
} }
*thread_count = gSems[slot].u.used.count; *thread_count = sSems[slot].u.used.count;
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
return B_NO_ERROR; return B_NO_ERROR;
@@ -691,7 +693,7 @@ _get_sem_info(sem_id id, struct sem_info *info, size_t size)
int state; int state;
int slot; int slot;
if (!gSemsActive) if (!sSemsActive)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (id < 0) if (id < 0)
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -701,15 +703,15 @@ _get_sem_info(sem_id id, struct sem_info *info, size_t size)
slot = id % sMaxSems; slot = id % sMaxSems;
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != id) { if (sSems[slot].id != id) {
status = B_BAD_SEM_ID; status = B_BAD_SEM_ID;
TRACE(("get_sem_info: invalid sem_id %ld\n", id)); TRACE(("get_sem_info: invalid sem_id %ld\n", id));
} else } else
fill_sem_info(&gSems[slot], info, size); fill_sem_info(&sSems[slot], info, size);
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
return status; return status;
@@ -729,14 +731,14 @@ _get_next_sem_info(team_id team, int32 *_cookie, struct sem_info *info, size_t s
int slot; int slot;
bool found = false; bool found = false;
if (!gSemsActive) if (!sSemsActive)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (_cookie == NULL || info == NULL || size != sizeof(sem_info)) if (_cookie == NULL || info == NULL || size != sizeof(sem_info))
return B_BAD_VALUE; return B_BAD_VALUE;
if (team == B_CURRENT_TEAM) if (team == B_CURRENT_TEAM)
team = team_get_current_team_id(); team = team_get_current_team_id();
/* prevents gSems[].owner == -1 >= means owned by a port */ /* prevents sSems[].owner == -1 >= means owned by a port */
if (team < 0 || !team_is_valid(team)) if (team < 0 || !team_is_valid(team))
return B_BAD_TEAM_ID; return B_BAD_TEAM_ID;
@@ -748,18 +750,18 @@ _get_next_sem_info(team_id team, int32 *_cookie, struct sem_info *info, size_t s
GRAB_SEM_LIST_LOCK(); GRAB_SEM_LIST_LOCK();
while (slot < sMaxSems) { while (slot < sMaxSems) {
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) { if (sSems[slot].id != -1 && sSems[slot].u.used.owner == team) {
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != -1 && gSems[slot].u.used.owner == team) { if (sSems[slot].id != -1 && sSems[slot].u.used.owner == team) {
// found one! // found one!
fill_sem_info(&gSems[slot], info, size); fill_sem_info(&sSems[slot], info, size);
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
slot++; slot++;
found = true; found = true;
break; break;
} }
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
} }
slot++; slot++;
} }
@@ -780,7 +782,7 @@ set_sem_owner(sem_id id, team_id team)
int state; int state;
int slot; int slot;
if (gSemsActive == false) if (sSemsActive == false)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
if (id < 0) if (id < 0)
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -790,10 +792,10 @@ set_sem_owner(sem_id id, team_id team)
slot = id % sMaxSems; slot = id % sMaxSems;
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != id) { if (sSems[slot].id != id) {
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
TRACE(("set_sem_owner: invalid sem_id %ld\n", id)); TRACE(("set_sem_owner: invalid sem_id %ld\n", id));
return B_BAD_SEM_ID; return B_BAD_SEM_ID;
@@ -804,9 +806,9 @@ set_sem_owner(sem_id id, team_id team)
// this case! // this case!
// The only safe way to do this is to prevent either team (the new // The only safe way to do this is to prevent either team (the new
// or the old owner) from dying until we leave the spinlock. // or the old owner) from dying until we leave the spinlock.
gSems[slot].u.used.owner = team; sSems[slot].u.used.owner = team;
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
restore_interrupts(state); restore_interrupts(state);
return B_NO_ERROR; return B_NO_ERROR;
@@ -833,17 +835,17 @@ sem_interrupt_thread(struct thread *t)
slot = t->sem.blocking % sMaxSems; slot = t->sem.blocking % sMaxSems;
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(sSems[slot]);
if (gSems[slot].id != t->sem.blocking) { if (sSems[slot].id != t->sem.blocking) {
panic("sem_interrupt_thread: thread 0x%lx sez it's blocking on sem 0x%lx, but that sem doesn't exist!\n", t->id, t->sem.blocking); panic("sem_interrupt_thread: thread 0x%lx sez it's blocking on sem 0x%lx, but that sem doesn't exist!\n", t->id, t->sem.blocking);
} }
wakeup_queue.head = wakeup_queue.tail = NULL; wakeup_queue.head = wakeup_queue.tail = NULL;
if (remove_thread_from_sem(t, &gSems[slot], &wakeup_queue, EINTR) != B_OK) if (remove_thread_from_sem(t, &sSems[slot], &wakeup_queue, EINTR) != B_OK)
panic("sem_interrupt_thread: thread 0x%lx not found in sem 0x%lx's wait queue\n", t->id, t->sem.blocking); panic("sem_interrupt_thread: thread 0x%lx not found in sem 0x%lx's wait queue\n", t->id, t->sem.blocking);
RELEASE_SEM_LOCK(gSems[slot]); RELEASE_SEM_LOCK(sSems[slot]);
while ((t = thread_dequeue(&wakeup_queue)) != NULL) { while ((t = thread_dequeue(&wakeup_queue)) != NULL) {
scheduler_enqueue_in_run_queue(t); scheduler_enqueue_in_run_queue(t);
@@ -902,6 +904,9 @@ sem_delete_owned_sems(team_id owner)
int i; int i;
int count = 0; int count = 0;
// ToDo: that looks horribly inefficient - maybe it would be better
// to have them in a list in the team
if (owner < 0) if (owner < 0)
return B_BAD_TEAM_ID; return B_BAD_TEAM_ID;
@@ -909,8 +914,8 @@ sem_delete_owned_sems(team_id owner)
GRAB_SEM_LIST_LOCK(); GRAB_SEM_LIST_LOCK();
for (i = 0; i < sMaxSems; i++) { for (i = 0; i < sMaxSems; i++) {
if (gSems[i].id != -1 && gSems[i].u.used.owner == owner) { if (sSems[i].id != -1 && sSems[i].u.used.owner == owner) {
sem_id id = gSems[i].id; sem_id id = sSems[i].id;
RELEASE_SEM_LIST_LOCK(); RELEASE_SEM_LIST_LOCK();
restore_interrupts(state); restore_interrupts(state);