]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/sys_reason.c
xnu-6153.81.5.tar.gz
[apple/xnu.git] / bsd / kern / sys_reason.c
index 518df53ab2b3fe21bc6ead368f023647147d3be3..70493f9741c3096e9b9b0b4f9ba2b6135e5c0f6f 100644 (file)
@@ -50,6 +50,8 @@ lck_grp_attr_t  *os_reason_lock_grp_attr;
 lck_grp_t       *os_reason_lock_grp;
 lck_attr_t      *os_reason_lock_attr;
 
+os_refgrp_decl(static, os_reason_refgrp, "os_reason", NULL);
+
 #define OS_REASON_RESERVE_COUNT 100
 #define OS_REASON_MAX_COUNT     (maxproc + 100)
 
@@ -131,7 +133,7 @@ os_reason_create(uint32_t osr_namespace, uint64_t osr_code)
        new_reason->osr_kcd_buf = NULL;
 
        lck_mtx_init(&new_reason->osr_lock, os_reason_lock_grp, os_reason_lock_attr);
-       new_reason->osr_refcount = 1;
+       os_ref_init(&new_reason->osr_refcount, &os_reason_refgrp);
 
        return new_reason;
 }
@@ -276,14 +278,8 @@ os_reason_ref(os_reason_t cur_reason)
        }
 
        lck_mtx_lock(&cur_reason->osr_lock);
-
-       assert(cur_reason->osr_refcount > 0);
-       if (os_add_overflow(cur_reason->osr_refcount, 1, &cur_reason->osr_refcount)) {
-               panic("os reason refcount overflow");
-       }
-
+       os_ref_retain_locked(&cur_reason->osr_refcount);
        lck_mtx_unlock(&cur_reason->osr_lock);
-
        return;
 }
 
@@ -300,12 +296,7 @@ os_reason_free(os_reason_t cur_reason)
 
        lck_mtx_lock(&cur_reason->osr_lock);
 
-       if (cur_reason->osr_refcount == 0) {
-               panic("os_reason_free called on reason with zero refcount");
-       }
-
-       cur_reason->osr_refcount--;
-       if (cur_reason->osr_refcount != 0) {
+       if (os_ref_release_locked(&cur_reason->osr_refcount) > 0) {
                lck_mtx_unlock(&cur_reason->osr_lock);
                return;
        }
@@ -317,3 +308,44 @@ os_reason_free(os_reason_t cur_reason)
 
        zfree(os_reason_zone, cur_reason);
 }
+
+/*
+ * Sets flags on the passed reason.
+ */
+void
+os_reason_set_flags(os_reason_t cur_reason, uint64_t flags)
+{
+       if (cur_reason == OS_REASON_NULL) {
+               return;
+       }
+
+       lck_mtx_lock(&cur_reason->osr_lock);
+       cur_reason->osr_flags = flags;
+       lck_mtx_unlock(&cur_reason->osr_lock);
+}
+
+/*
+ * Allocates space and sets description data in kcd_descriptor on the passed reason.
+ */
+void
+os_reason_set_description_data(os_reason_t cur_reason, uint32_t type, void *reason_data, uint32_t reason_data_len)
+{
+       mach_vm_address_t osr_data_addr = 0;
+
+       if (cur_reason == OS_REASON_NULL) {
+               return;
+       }
+
+       if (0 != os_reason_alloc_buffer(cur_reason, kcdata_estimate_required_buffer_size(1, reason_data_len))) {
+               panic("os_reason failed to allocate");
+       }
+
+       lck_mtx_lock(&cur_reason->osr_lock);
+       if (KERN_SUCCESS != kcdata_get_memory_addr(&cur_reason->osr_kcd_descriptor, type, reason_data_len, &osr_data_addr)) {
+               panic("os_reason failed to get data address");
+       }
+       if (KERN_SUCCESS != kcdata_memcpy(&cur_reason->osr_kcd_descriptor, osr_data_addr, reason_data, reason_data_len)) {
+               panic("os_reason failed to copy description data");
+       }
+       lck_mtx_unlock(&cur_reason->osr_lock);
+}