Moved the thread::sem fields into their own sub-structure for clarity.

Some minor cleanups.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9328 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-10-13 15:19:08 +00:00
parent 7533ce05e9
commit 1956e69d13
2 changed files with 60 additions and 57 deletions
+52 -49
View File
@@ -67,7 +67,8 @@ static spinlock sem_spinlock = 0;
#define GRAB_SEM_LOCK(s) acquire_spinlock(&(s).lock) #define GRAB_SEM_LOCK(s) acquire_spinlock(&(s).lock)
#define RELEASE_SEM_LOCK(s) release_spinlock(&(s).lock) #define RELEASE_SEM_LOCK(s) release_spinlock(&(s).lock)
static int remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struct thread_queue *queue, int sem_errcode); static int remove_thread_from_sem(struct thread *t, struct sem_entry *sem,
struct thread_queue *queue, status_t acquireStatus);
struct sem_timeout_args { struct sem_timeout_args {
thread_id blocked_thread; thread_id blocked_thread;
@@ -148,17 +149,18 @@ dump_sem_info(int argc, char **argv)
return 0; return 0;
} }
/*! \brief Appends a semaphore slot to the free list.
The semaphore list must be locked. /** \brief Appends a semaphore slot to the free list.
The slot's id field is not changed. It should already be set to -1. *
* The semaphore list must be locked.
* The slot's id field is not changed. It should already be set to -1.
*
* \param slot The index of the semaphore slot.
* \param nextID The ID the slot will get when reused. If < 0 the \a slot
* is used.
*/
\param slot The index of the semaphore slot. static void
\param nextID The ID the slot will get when reused. If < 0 the \a slot
is used.
*/
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 = gSems + slot;
@@ -220,10 +222,10 @@ sem_id
create_sem_etc(int32 count, const char *name, team_id owner) create_sem_etc(int32 count, const char *name, team_id owner)
{ {
struct sem_entry *sem = NULL; struct sem_entry *sem = NULL;
int state; cpu_status state;
sem_id retval = B_NO_MORE_SEMS; sem_id id = B_NO_MORE_SEMS;
char *temp_name; char *tempName;
int name_len; size_t nameLength;
if (gSemsActive == false || sUsedSems == sMaxSems) if (gSemsActive == false || sUsedSems == sMaxSems)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
@@ -231,12 +233,12 @@ create_sem_etc(int32 count, const char *name, team_id owner)
if (name == NULL) if (name == NULL)
name = "unnamed semaphore"; name = "unnamed semaphore";
name_len = strlen(name) + 1; nameLength = strlen(name) + 1;
name_len = min(name_len, SYS_MAX_OS_NAME_LEN); nameLength = min(nameLength, B_OS_NAME_LENGTH);
temp_name = (char *)malloc(name_len); tempName = (char *)malloc(nameLength);
if (temp_name == NULL) if (tempName == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
strlcpy(temp_name, name, name_len); strlcpy(tempName, name, nameLength);
state = disable_interrupts(); state = disable_interrupts();
GRAB_SEM_LIST_LOCK(); GRAB_SEM_LIST_LOCK();
@@ -254,9 +256,9 @@ create_sem_etc(int32 count, const char *name, team_id owner)
sem->u.used.count = count; sem->u.used.count = count;
sem->u.used.q.tail = NULL; sem->u.used.q.tail = NULL;
sem->u.used.q.head = NULL; sem->u.used.q.head = NULL;
sem->u.used.name = temp_name; sem->u.used.name = tempName;
sem->u.used.owner = owner; sem->u.used.owner = owner;
retval = sem->id; id = sem->id;
RELEASE_SEM_LOCK(*sem); RELEASE_SEM_LOCK(*sem);
atomic_add(&sUsedSems, 1); atomic_add(&sUsedSems, 1);
@@ -266,9 +268,9 @@ create_sem_etc(int32 count, const char *name, team_id owner)
restore_interrupts(state); restore_interrupts(state);
if (!sem) if (!sem)
free(temp_name); free(tempName);
return retval; return id;
} }
@@ -312,8 +314,8 @@ delete_sem(sem_id id)
// 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(&gSems[slot].u.used.q)) != NULL) {
t->state = B_THREAD_READY; t->state = B_THREAD_READY;
t->sem_errcode = B_BAD_SEM_ID; t->sem.acquire_status = B_BAD_SEM_ID;
t->sem_count = 0; t->sem.count = 0;
thread_enqueue(t, &release_queue); thread_enqueue(t, &release_queue);
released_threads++; released_threads++;
} }
@@ -451,12 +453,12 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
} }
t->next_state = B_THREAD_WAITING; t->next_state = B_THREAD_WAITING;
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(-gSems[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_errcode = B_NO_ERROR; t->sem.acquire_status = B_NO_ERROR;
thread_enqueue(t, &gSems[slot].u.used.q); thread_enqueue(t, &gSems[slot].u.used.q);
if ((flags & (B_TIMEOUT | B_ABSOLUTE_TIMEOUT)) != 0) { if ((flags & (B_TIMEOUT | B_ABSOLUTE_TIMEOUT)) != 0) {
@@ -500,7 +502,7 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
RELEASE_THREAD_LOCK(); RELEASE_THREAD_LOCK();
if ((flags & (B_TIMEOUT | B_ABSOLUTE_TIMEOUT)) != 0) { if ((flags & (B_TIMEOUT | B_ABSOLUTE_TIMEOUT)) != 0) {
if (t->sem_errcode != B_TIMED_OUT) { if (t->sem.acquire_status != B_TIMED_OUT) {
// cancel the timer event, the sem may have been deleted or interrupted // cancel the timer event, the sem may have been deleted or interrupted
// with the timer still active // with the timer still active
cancel_timer(&timeout_timer); cancel_timer(&timeout_timer);
@@ -512,7 +514,7 @@ acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout)
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, gSems[slot].u.used.name, t,
t->name)); t->name));
return t->sem_errcode; return t->sem.acquire_status;
} }
err: err:
@@ -566,15 +568,15 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
if (gSems[slot].u.used.count < 0) { if (gSems[slot].u.used.count < 0) {
struct thread *t = thread_lookat_queue(&gSems[slot].u.used.q); struct thread *t = thread_lookat_queue(&gSems[slot].u.used.q);
delta = min(count, t->sem_count); delta = min(count, t->sem.count);
t->sem_count -= delta; t->sem.count -= delta;
if (t->sem_count <= 0) { if (t->sem.count <= 0) {
// release this thread // release this thread
t = thread_dequeue(&gSems[slot].u.used.q); t = thread_dequeue(&gSems[slot].u.used.q);
thread_enqueue(t, &release_queue); thread_enqueue(t, &release_queue);
t->state = B_THREAD_READY; t->state = B_THREAD_READY;
released_threads++; released_threads++;
t->sem_count = 0; t->sem.count = 0;
} }
} }
@@ -809,24 +811,24 @@ sem_interrupt_thread(struct thread *t)
struct thread_queue wakeup_queue; struct thread_queue wakeup_queue;
TRACE(("sem_interrupt_thread: called on thread %p (%d), blocked on sem 0x%x\n", TRACE(("sem_interrupt_thread: called on thread %p (%d), blocked on sem 0x%x\n",
t, t->id, t->sem_blocking)); t, t->id, t->sem.blocking));
if (t->state != B_THREAD_WAITING || t->sem_blocking < 0) if (t->state != B_THREAD_WAITING || t->sem.blocking < 0)
return B_BAD_VALUE; return B_BAD_VALUE;
if (!(t->sem_flags & B_CAN_INTERRUPT)) if (!(t->sem.flags & B_CAN_INTERRUPT))
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
slot = t->sem_blocking % sMaxSems; slot = t->sem.blocking % sMaxSems;
GRAB_SEM_LOCK(gSems[slot]); GRAB_SEM_LOCK(gSems[slot]);
if (gSems[slot].id != t->sem_blocking) { if (gSems[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, &gSems[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(gSems[slot]);
@@ -844,7 +846,8 @@ sem_interrupt_thread(struct thread *t)
*/ */
static int static int
remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struct thread_queue *queue, int sem_errcode) remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struct thread_queue *queue,
status_t acquireStatus)
{ {
struct thread *t1; struct thread *t1;
@@ -853,18 +856,18 @@ remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struct thread_qu
if (t != t1) if (t != t1)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
sem->u.used.count += t->sem_acquire_count; sem->u.used.count += t->sem.acquire_count;
t->state = t->next_state = B_THREAD_READY; t->state = t->next_state = B_THREAD_READY;
t->sem_errcode = sem_errcode; t->sem.acquire_status = acquireStatus;
thread_enqueue(t, queue); thread_enqueue(t, queue);
// now see if more threads need to be woken up // now see if more threads need to be woken up
while (sem->u.used.count > 0 while (sem->u.used.count > 0
&& (t1 = thread_lookat_queue(&sem->u.used.q))) { && (t1 = thread_lookat_queue(&sem->u.used.q))) {
int delta = min(t->sem_count, sem->u.used.count); int delta = min(t->sem.count, sem->u.used.count);
t->sem_count -= delta; t->sem.count -= delta;
if (t->sem_count <= 0) { if (t->sem.count <= 0) {
t = thread_dequeue(&sem->u.used.q); t = thread_dequeue(&sem->u.used.q);
t->state = t->next_state = B_THREAD_READY; t->state = t->next_state = B_THREAD_READY;
thread_enqueue(t, queue); thread_enqueue(t, queue);
+8 -8
View File
@@ -159,7 +159,7 @@ create_thread_struct(const char *name)
t->id = atomic_add(&sNextThreadID, 1); t->id = atomic_add(&sNextThreadID, 1);
t->team = NULL; t->team = NULL;
t->cpu = NULL; t->cpu = NULL;
t->sem_blocking = -1; t->sem.blocking = -1;
t->fault_handler = 0; t->fault_handler = 0;
t->page_faults_allowed = 1; t->page_faults_allowed = 1;
t->kernel_stack_region_id = -1; t->kernel_stack_region_id = -1;
@@ -440,10 +440,10 @@ _dump_thread_info(struct thread *t)
dprintf("\n"); dprintf("\n");
dprintf("sig_pending: 0x%lx\n", t->sig_pending); dprintf("sig_pending: 0x%lx\n", t->sig_pending);
dprintf("in_kernel: %d\n", t->in_kernel); dprintf("in_kernel: %d\n", t->in_kernel);
dprintf("sem_blocking: 0x%lx\n", t->sem_blocking); dprintf("sem.blocking: 0x%lx\n", t->sem.blocking);
dprintf("sem_count: 0x%x\n", t->sem_count); dprintf("sem.count: 0x%x\n", t->sem.count);
dprintf("sem_errcode: 0x%x\n", t->sem_errcode); dprintf("sem.acquire_status: 0x%x\n", t->sem.acquire_status);
dprintf("sem_flags: 0x%x\n", t->sem_flags); dprintf("sem.flags: 0x%x\n", t->sem.flags);
dprintf("fault_handler: %p\n", (void *)t->fault_handler); dprintf("fault_handler: %p\n", (void *)t->fault_handler);
dprintf("args: %p %p\n", t->args1, t->args2); dprintf("args: %p %p\n", t->args1, t->args2);
dprintf("entry: %p\n", (void *)t->entry); dprintf("entry: %p\n", (void *)t->entry);
@@ -1280,9 +1280,9 @@ fill_thread_info(struct thread *thread, thread_info *info, size_t size)
strlcpy(info->name, thread->name, B_OS_NAME_LENGTH); strlcpy(info->name, thread->name, B_OS_NAME_LENGTH);
if (thread->state == B_THREAD_WAITING) { if (thread->state == B_THREAD_WAITING) {
if (thread->sem_blocking == sSnoozeSem) if (thread->sem.blocking == sSnoozeSem)
info->state = B_THREAD_ASLEEP; info->state = B_THREAD_ASLEEP;
else if (thread->sem_blocking == thread->msg.read_sem) else if (thread->sem.blocking == thread->msg.read_sem)
info->state = B_THREAD_RECEIVING; info->state = B_THREAD_RECEIVING;
else else
info->state = B_THREAD_WAITING; info->state = B_THREAD_WAITING;
@@ -1290,7 +1290,7 @@ fill_thread_info(struct thread *thread, thread_info *info, size_t size)
info->state = thread->state; info->state = thread->state;
info->priority = thread->priority; info->priority = thread->priority;
info->sem = thread->sem_blocking; info->sem = thread->sem.blocking;
info->user_time = thread->user_time; info->user_time = thread->user_time;
info->kernel_time = thread->kernel_time; info->kernel_time = thread->kernel_time;
info->stack_base = (void *)thread->user_stack_base; info->stack_base = (void *)thread->user_stack_base;