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:
+52
-49
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user