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:
parent
7533ce05e9
commit
1956e69d13
@ -67,7 +67,8 @@ static spinlock sem_spinlock = 0;
|
||||
#define GRAB_SEM_LOCK(s) acquire_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 {
|
||||
thread_id blocked_thread;
|
||||
@ -148,17 +149,18 @@ dump_sem_info(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief Appends a semaphore slot to the free list.
|
||||
|
||||
The semaphore list must be locked.
|
||||
The slot's id field is not changed. It should already be set to -1.
|
||||
/** \brief Appends a semaphore slot to the free list.
|
||||
*
|
||||
* 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.
|
||||
\param nextID The ID the slot will get when reused. If < 0 the \a slot
|
||||
is used.
|
||||
*/
|
||||
static
|
||||
void
|
||||
static void
|
||||
free_sem_slot(int slot, sem_id nextID)
|
||||
{
|
||||
struct sem_entry *sem = gSems + slot;
|
||||
@ -220,10 +222,10 @@ sem_id
|
||||
create_sem_etc(int32 count, const char *name, team_id owner)
|
||||
{
|
||||
struct sem_entry *sem = NULL;
|
||||
int state;
|
||||
sem_id retval = B_NO_MORE_SEMS;
|
||||
char *temp_name;
|
||||
int name_len;
|
||||
cpu_status state;
|
||||
sem_id id = B_NO_MORE_SEMS;
|
||||
char *tempName;
|
||||
size_t nameLength;
|
||||
|
||||
if (gSemsActive == false || sUsedSems == sMaxSems)
|
||||
return B_NO_MORE_SEMS;
|
||||
@ -231,12 +233,12 @@ create_sem_etc(int32 count, const char *name, team_id owner)
|
||||
if (name == NULL)
|
||||
name = "unnamed semaphore";
|
||||
|
||||
name_len = strlen(name) + 1;
|
||||
name_len = min(name_len, SYS_MAX_OS_NAME_LEN);
|
||||
temp_name = (char *)malloc(name_len);
|
||||
if (temp_name == NULL)
|
||||
nameLength = strlen(name) + 1;
|
||||
nameLength = min(nameLength, B_OS_NAME_LENGTH);
|
||||
tempName = (char *)malloc(nameLength);
|
||||
if (tempName == NULL)
|
||||
return B_NO_MEMORY;
|
||||
strlcpy(temp_name, name, name_len);
|
||||
strlcpy(tempName, name, nameLength);
|
||||
|
||||
state = disable_interrupts();
|
||||
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.q.tail = NULL;
|
||||
sem->u.used.q.head = NULL;
|
||||
sem->u.used.name = temp_name;
|
||||
sem->u.used.name = tempName;
|
||||
sem->u.used.owner = owner;
|
||||
retval = sem->id;
|
||||
id = sem->id;
|
||||
RELEASE_SEM_LOCK(*sem);
|
||||
|
||||
atomic_add(&sUsedSems, 1);
|
||||
@ -266,9 +268,9 @@ create_sem_etc(int32 count, const char *name, team_id owner)
|
||||
restore_interrupts(state);
|
||||
|
||||
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
|
||||
while ((t = thread_dequeue(&gSems[slot].u.used.q)) != NULL) {
|
||||
t->state = B_THREAD_READY;
|
||||
t->sem_errcode = B_BAD_SEM_ID;
|
||||
t->sem_count = 0;
|
||||
t->sem.acquire_status = B_BAD_SEM_ID;
|
||||
t->sem.count = 0;
|
||||
thread_enqueue(t, &release_queue);
|
||||
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->sem_flags = flags;
|
||||
t->sem_blocking = id;
|
||||
t->sem_acquire_count = count;
|
||||
t->sem_count = min(-gSems[slot].u.used.count, count);
|
||||
t->sem.flags = flags;
|
||||
t->sem.blocking = id;
|
||||
t->sem.acquire_count = count;
|
||||
t->sem.count = min(-gSems[slot].u.used.count, count);
|
||||
// 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);
|
||||
|
||||
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();
|
||||
|
||||
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
|
||||
// with the timer still active
|
||||
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, "
|
||||
"thread = %p (%s)\n", id, gSems[slot].u.used.name, t,
|
||||
t->name));
|
||||
return t->sem_errcode;
|
||||
return t->sem.acquire_status;
|
||||
}
|
||||
|
||||
err:
|
||||
@ -566,15 +568,15 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
|
||||
if (gSems[slot].u.used.count < 0) {
|
||||
struct thread *t = thread_lookat_queue(&gSems[slot].u.used.q);
|
||||
|
||||
delta = min(count, t->sem_count);
|
||||
t->sem_count -= delta;
|
||||
if (t->sem_count <= 0) {
|
||||
delta = min(count, t->sem.count);
|
||||
t->sem.count -= delta;
|
||||
if (t->sem.count <= 0) {
|
||||
// release this thread
|
||||
t = thread_dequeue(&gSems[slot].u.used.q);
|
||||
thread_enqueue(t, &release_queue);
|
||||
t->state = B_THREAD_READY;
|
||||
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;
|
||||
|
||||
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;
|
||||
if (!(t->sem_flags & B_CAN_INTERRUPT))
|
||||
if (!(t->sem.flags & B_CAN_INTERRUPT))
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
slot = t->sem_blocking % sMaxSems;
|
||||
slot = t->sem.blocking % sMaxSems;
|
||||
|
||||
GRAB_SEM_LOCK(gSems[slot]);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
wakeup_queue.head = wakeup_queue.tail = NULL;
|
||||
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]);
|
||||
|
||||
@ -844,7 +846,8 @@ sem_interrupt_thread(struct thread *t)
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
@ -853,18 +856,18 @@ remove_thread_from_sem(struct thread *t, struct sem_entry *sem, struct thread_qu
|
||||
if (t != t1)
|
||||
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->sem_errcode = sem_errcode;
|
||||
t->sem.acquire_status = acquireStatus;
|
||||
thread_enqueue(t, queue);
|
||||
|
||||
// now see if more threads need to be woken up
|
||||
while (sem->u.used.count > 0
|
||||
&& (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;
|
||||
if (t->sem_count <= 0) {
|
||||
t->sem.count -= delta;
|
||||
if (t->sem.count <= 0) {
|
||||
t = thread_dequeue(&sem->u.used.q);
|
||||
t->state = t->next_state = B_THREAD_READY;
|
||||
thread_enqueue(t, queue);
|
||||
|
@ -159,7 +159,7 @@ create_thread_struct(const char *name)
|
||||
t->id = atomic_add(&sNextThreadID, 1);
|
||||
t->team = NULL;
|
||||
t->cpu = NULL;
|
||||
t->sem_blocking = -1;
|
||||
t->sem.blocking = -1;
|
||||
t->fault_handler = 0;
|
||||
t->page_faults_allowed = 1;
|
||||
t->kernel_stack_region_id = -1;
|
||||
@ -440,10 +440,10 @@ _dump_thread_info(struct thread *t)
|
||||
dprintf("\n");
|
||||
dprintf("sig_pending: 0x%lx\n", t->sig_pending);
|
||||
dprintf("in_kernel: %d\n", t->in_kernel);
|
||||
dprintf("sem_blocking: 0x%lx\n", t->sem_blocking);
|
||||
dprintf("sem_count: 0x%x\n", t->sem_count);
|
||||
dprintf("sem_errcode: 0x%x\n", t->sem_errcode);
|
||||
dprintf("sem_flags: 0x%x\n", t->sem_flags);
|
||||
dprintf("sem.blocking: 0x%lx\n", t->sem.blocking);
|
||||
dprintf("sem.count: 0x%x\n", t->sem.count);
|
||||
dprintf("sem.acquire_status: 0x%x\n", t->sem.acquire_status);
|
||||
dprintf("sem.flags: 0x%x\n", t->sem.flags);
|
||||
dprintf("fault_handler: %p\n", (void *)t->fault_handler);
|
||||
dprintf("args: %p %p\n", t->args1, t->args2);
|
||||
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);
|
||||
|
||||
if (thread->state == B_THREAD_WAITING) {
|
||||
if (thread->sem_blocking == sSnoozeSem)
|
||||
if (thread->sem.blocking == sSnoozeSem)
|
||||
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;
|
||||
else
|
||||
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->priority = thread->priority;
|
||||
info->sem = thread->sem_blocking;
|
||||
info->sem = thread->sem.blocking;
|
||||
info->user_time = thread->user_time;
|
||||
info->kernel_time = thread->kernel_time;
|
||||
info->stack_base = (void *)thread->user_stack_base;
|
||||
|
Loading…
x
Reference in New Issue
Block a user