X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/4bd07ac2140668789aa3ee8ec4dde4a3e0a3bba5..d9a64523371fa019c4575bb400cbbc3a50ac9903:/osfmk/kern/sync_sema.c diff --git a/osfmk/kern/sync_sema.c b/osfmk/kern/sync_sema.c index 4304559e6..98f33ba8d 100644 --- a/osfmk/kern/sync_sema.c +++ b/osfmk/kern/sync_sema.c @@ -66,6 +66,8 @@ static unsigned int semaphore_event; zone_t semaphore_zone; unsigned int semaphore_max; +os_refgrp_decl(static, sema_refgrp, "semaphore", NULL); + /* Forward declarations */ @@ -184,7 +186,7 @@ semaphore_create( * Initialize the semaphore values. */ s->port = IP_NULL; - s->ref_count = 1; + os_ref_init(&s->ref_count, &sema_refgrp); s->count = value; s->active = TRUE; s->owner = task; @@ -280,11 +282,12 @@ semaphore_destroy( if (semaphore->owner != task) { semaphore_unlock(semaphore); + semaphore_dereference(semaphore); splx(spl_level); task_unlock(task); return KERN_INVALID_ARGUMENT; } - + semaphore_destroy_internal(task, semaphore); /* semaphore unlocked */ @@ -687,7 +690,8 @@ semaphore_wait_internal( thread_t self = current_thread(); wait_semaphore->count = -1; /* we don't keep an actual count */ - thread_lock(self); + + thread_set_pending_block_hint(self, kThreadWaitSemaphore); (void)waitq_assert_wait64_locked( &wait_semaphore->waitq, SEMAPHORE_EVENT, @@ -695,7 +699,6 @@ semaphore_wait_internal( TIMEOUT_URGENCY_USER_NORMAL, deadline, TIMEOUT_NO_LEEWAY, self); - thread_unlock(self); } semaphore_unlock(wait_semaphore); splx(spl_level); @@ -1105,7 +1108,7 @@ void semaphore_reference( semaphore_t semaphore) { - (void)hw_atomic_add(&semaphore->ref_count, 1); + os_ref_retain(&semaphore->ref_count); } /* @@ -1124,8 +1127,9 @@ semaphore_dereference( if (semaphore == NULL) return; - if (hw_atomic_sub(&semaphore->ref_count, 1) != 0) + if (os_ref_release(&semaphore->ref_count) > 0) { return; + } /* * Last ref, clean up the port [if any] @@ -1173,4 +1177,15 @@ semaphore_dereference( zfree(semaphore_zone, semaphore); } +#define WAITQ_TO_SEMA(wq) ((semaphore_t) ((uintptr_t)(wq) - offsetof(struct semaphore, waitq))) +void +kdp_sema_find_owner(struct waitq * waitq, __assert_only event64_t event, thread_waitinfo_t * waitinfo) +{ + semaphore_t sem = WAITQ_TO_SEMA(waitq); + assert(event == SEMAPHORE_EVENT); + assert(kdp_is_in_zone(sem, "semaphores")); + waitinfo->context = VM_KERNEL_UNSLIDE_OR_PERM(sem->port); + if (sem->owner) + waitinfo->owner = pid_from_task(sem->owner); +}