]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/dtrace/dtrace_glue.c
xnu-4570.20.62.tar.gz
[apple/xnu.git] / bsd / dev / dtrace / dtrace_glue.c
index d7588c0caadca4f562cca86f62732da1aaef3d18..57f0f32071ea82bad86897a8127229d3fce8d6b2 100644 (file)
 #include <vm/pmap.h>
 #include <vm/vm_map.h> /* All the bits we care about are guarded by MACH_KERNEL_PRIVATE :-( */
 
 #include <vm/pmap.h>
 #include <vm/vm_map.h> /* All the bits we care about are guarded by MACH_KERNEL_PRIVATE :-( */
 
-/* missing prototypes, not exported by Mach */
-extern kern_return_t task_suspend_internal(task_t);
-extern kern_return_t task_resume_internal(task_t);
-
 /*
  * pid/proc
  */
 /*
  * pid/proc
  */
@@ -301,6 +297,16 @@ typedef struct wrap_timer_call {
 #define WAKEUP_REAPER          0x7FFFFFFFFFFFFFFFLL
 #define NEARLY_FOREVER         0x7FFFFFFFFFFFFFFELL
 
 #define WAKEUP_REAPER          0x7FFFFFFFFFFFFFFFLL
 #define NEARLY_FOREVER         0x7FFFFFFFFFFFFFFELL
 
+
+typedef struct cyc_list {
+       cyc_omni_handler_t cyl_omni;
+       wrap_timer_call_t cyl_wrap_by_cpus[];
+#if __arm__ && (__BIGGEST_ALIGNMENT__ > 4)
+} __attribute__ ((aligned (8))) cyc_list_t;
+#else
+} cyc_list_t;
+#endif
+
 /* CPU going online/offline notifications */
 void (*dtrace_cpu_state_changed_hook)(int, boolean_t) = NULL;
 void dtrace_cpu_state_changed(int, boolean_t);
 /* CPU going online/offline notifications */
 void (*dtrace_cpu_state_changed_hook)(int, boolean_t) = NULL;
 void dtrace_cpu_state_changed(int, boolean_t);
@@ -390,10 +396,8 @@ timer_call_add_cyclic(wrap_timer_call_t *wrapTC, cyc_handler_t *handler, cyc_tim
  * Executed on the CPU the timer is running on.
  */
 static void
  * Executed on the CPU the timer is running on.
  */
 static void
-timer_call_remove_cyclic(cyclic_id_t cyclic)
+timer_call_remove_cyclic(wrap_timer_call_t *wrapTC)
 {
 {
-       wrap_timer_call_t *wrapTC = (wrap_timer_call_t *)cyclic;
-
        assert(wrapTC);
        assert(cpu_number() == wrapTC->cpuid);
 
        assert(wrapTC);
        assert(cpu_number() == wrapTC->cpuid);
 
@@ -404,12 +408,10 @@ timer_call_remove_cyclic(cyclic_id_t cyclic)
 }
 
 static void *
 }
 
 static void *
-timer_call_get_cyclic_arg(cyclic_id_t cyclic)
-{       
-       wrap_timer_call_t *wrapTC = (wrap_timer_call_t *)cyclic;
-       
+timer_call_get_cyclic_arg(wrap_timer_call_t *wrapTC)
+{
        return (wrapTC ? wrapTC->hdlr.cyh_arg : NULL);
        return (wrapTC ? wrapTC->hdlr.cyh_arg : NULL);
-}   
+}
 
 cyclic_id_t
 cyclic_timer_add(cyc_handler_t *handler, cyc_time_t *when)
 
 cyclic_id_t
 cyclic_timer_add(cyc_handler_t *handler, cyc_time_t *when)
@@ -434,62 +436,48 @@ cyclic_timer_remove(cyclic_id_t cyclic)
 }
 
 static void
 }
 
 static void
-_cyclic_add_omni(cyclic_id_list_t cyc_list)
+_cyclic_add_omni(cyc_list_t *cyc_list)
 {
        cyc_time_t cT;
        cyc_handler_t cH;
 {
        cyc_time_t cT;
        cyc_handler_t cH;
-       wrap_timer_call_t *wrapTC;
-       cyc_omni_handler_t *omni = (cyc_omni_handler_t *)cyc_list;
-       char *t;
+       cyc_omni_handler_t *omni = &cyc_list->cyl_omni;
 
 
-       (omni->cyo_online)(omni->cyo_arg, CPU, &cH, &cT); 
+       (omni->cyo_online)(omni->cyo_arg, CPU, &cH, &cT);
 
 
-       t = (char *)cyc_list;
-       t += sizeof(cyc_omni_handler_t);
-       cyc_list = (cyclic_id_list_t)(uintptr_t)t;
-
-       t += sizeof(cyclic_id_t)*NCPU;
-       t += (sizeof(wrap_timer_call_t))*cpu_number();
-       wrapTC = (wrap_timer_call_t *)(uintptr_t)t;
-
-       cyc_list[cpu_number()] = timer_call_add_cyclic(wrapTC, &cH, &cT);
+       wrap_timer_call_t *wrapTC = &cyc_list->cyl_wrap_by_cpus[cpu_number()];
+       timer_call_add_cyclic(wrapTC, &cH, &cT);
 }
 
 cyclic_id_list_t
 cyclic_add_omni(cyc_omni_handler_t *omni)
 {
 }
 
 cyclic_id_list_t
 cyclic_add_omni(cyc_omni_handler_t *omni)
 {
-       cyclic_id_list_t cyc_list = 
-               _MALLOC( (sizeof(wrap_timer_call_t))*NCPU + 
-                                sizeof(cyclic_id_t)*NCPU + 
-                                sizeof(cyc_omni_handler_t), M_TEMP, M_ZERO | M_WAITOK);
+       cyc_list_t *cyc_list =
+               _MALLOC(sizeof(cyc_list_t) + NCPU * sizeof(wrap_timer_call_t), M_TEMP, M_ZERO | M_WAITOK);
+
        if (NULL == cyc_list)
        if (NULL == cyc_list)
-               return (cyclic_id_list_t)CYCLIC_NONE;
+               return NULL;
+
+       cyc_list->cyl_omni = *omni;
 
 
-       *(cyc_omni_handler_t *)cyc_list = *omni;
        dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)_cyclic_add_omni, (void *)cyc_list);
 
        dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)_cyclic_add_omni, (void *)cyc_list);
 
-       return cyc_list;
+       return (cyclic_id_list_t)cyc_list;
 }
 
 static void
 }
 
 static void
-_cyclic_remove_omni(cyclic_id_list_t cyc_list)
+_cyclic_remove_omni(cyc_list_t *cyc_list)
 {
 {
-       cyc_omni_handler_t *omni = (cyc_omni_handler_t *)cyc_list;
+       cyc_omni_handler_t *omni = &cyc_list->cyl_omni;
        void *oarg;
        void *oarg;
-       cyclic_id_t cid;
-       char *t;
-
-       t = (char *)cyc_list;
-       t += sizeof(cyc_omni_handler_t);
-       cyc_list = (cyclic_id_list_t)(uintptr_t)t;
+       wrap_timer_call_t *wrapTC;
 
        /*
         * If the processor was offline when dtrace started, we did not allocate
         * a cyclic timer for this CPU.
         */
 
        /*
         * If the processor was offline when dtrace started, we did not allocate
         * a cyclic timer for this CPU.
         */
-       if ((cid = cyc_list[cpu_number()]) != CYCLIC_NONE) {
-               oarg = timer_call_get_cyclic_arg(cid);
-               timer_call_remove_cyclic(cid);
+       if ((wrapTC = &cyc_list->cyl_wrap_by_cpus[cpu_number()]) != NULL) {
+               oarg = timer_call_get_cyclic_arg(wrapTC);
+               timer_call_remove_cyclic(wrapTC);
                (omni->cyo_offline)(omni->cyo_arg, CPU, oarg);
        }
 }
                (omni->cyo_offline)(omni->cyo_arg, CPU, oarg);
        }
 }
@@ -497,7 +485,7 @@ _cyclic_remove_omni(cyclic_id_list_t cyc_list)
 void
 cyclic_remove_omni(cyclic_id_list_t cyc_list)
 {
 void
 cyclic_remove_omni(cyclic_id_list_t cyc_list)
 {
-       ASSERT( cyc_list != (cyclic_id_list_t)CYCLIC_NONE );
+       ASSERT(cyc_list != NULL);
 
        dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)_cyclic_remove_omni, (void *)cyc_list);
        _FREE(cyc_list, M_TEMP);
 
        dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)_cyclic_remove_omni, (void *)cyc_list);
        _FREE(cyc_list, M_TEMP);
@@ -589,29 +577,6 @@ cyclic_remove(cyclic_id_t cyclic)
        }
 }
 
        }
 }
 
-/*
- * timeout / untimeout (converted to dtrace_timeout / dtrace_untimeout due to name collision)
- */ 
-
-thread_call_t
-dtrace_timeout(void (*func)(void *, void *), void* arg, uint64_t nanos)
-{
-#pragma unused(arg)
-       thread_call_t call = thread_call_allocate(func, NULL);
-
-       nanoseconds_to_absolutetime(nanos, &nanos);
-
-       /*
-        * This method does not use clock_deadline_for_periodic_event() because it is a one-shot,
-        * and clock drift on later invocations is not a worry.
-        */
-       uint64_t deadline = mach_absolute_time() + nanos;
-       /* DRK: consider using a lower priority callout here */
-       thread_call_enter_delayed(call, deadline);
-
-       return call;
-}
-
 /*
  * ddi
  */
 /*
  * ddi
  */
@@ -621,54 +586,6 @@ ddi_report_dev(dev_info_t *devi)
 #pragma unused(devi)
 }
 
 #pragma unused(devi)
 }
 
-#define NSOFT_STATES 32 /* XXX No more than 32 clients at a time, please. */
-static void *soft[NSOFT_STATES];
-
-int
-ddi_soft_state_init(void **state_p, size_t size, size_t n_items)
-{
-#pragma unused(n_items)
-       int i;
-       
-       for (i = 0; i < NSOFT_STATES; ++i) soft[i] = _MALLOC(size, M_TEMP, M_ZERO | M_WAITOK);
-       *(size_t *)state_p = size;
-       return 0;
-}
-
-int
-ddi_soft_state_zalloc(void *state, int item)
-{
-#pragma unused(state)
-       if (item < NSOFT_STATES)
-               return DDI_SUCCESS;
-       else
-               return DDI_FAILURE;
-}
-
-void *
-ddi_get_soft_state(void *state, int item)
-{
-#pragma unused(state)
-       ASSERT(item < NSOFT_STATES);
-       return soft[item];
-}
-
-int
-ddi_soft_state_free(void *state, int item)
-{
-       ASSERT(item < NSOFT_STATES);
-       bzero( soft[item], (size_t)state );
-       return DDI_SUCCESS;
-}
-
-void
-ddi_soft_state_fini(void **state_p)
-{
-#pragma unused(state_p)
-       int i;
-       
-       for (i = 0; i < NSOFT_STATES; ++i) _FREE( soft[i], M_TEMP );
-}
 
 static unsigned int gRegisteredProps = 0;
 static struct {
 
 static unsigned int gRegisteredProps = 0;
 static struct {
@@ -1313,6 +1230,30 @@ dtrace_copyoutstr(uintptr_t src, user_addr_t dst, size_t len, volatile uint16_t
        }
 }
 
        }
 }
 
+extern const int copysize_limit_panic;
+
+int
+dtrace_buffer_copyout(const void *kaddr, user_addr_t uaddr, vm_size_t nbytes)
+{
+       /*
+        * Partition the copyout in copysize_limit_panic-sized chunks
+        */
+       while (nbytes >= (vm_size_t)copysize_limit_panic) {
+               if (copyout(kaddr, uaddr, copysize_limit_panic) != 0)
+                       return (EFAULT);
+
+               nbytes -= copysize_limit_panic;
+               uaddr += copysize_limit_panic;
+               kaddr += copysize_limit_panic;
+       }
+       if (nbytes > 0) {
+               if (copyout(kaddr, uaddr, nbytes) != 0)
+                       return (EFAULT);
+       }
+
+       return (0);
+}
+
 uint8_t
 dtrace_fuword8(user_addr_t uaddr)
 {
 uint8_t
 dtrace_fuword8(user_addr_t uaddr)
 {
@@ -1547,6 +1488,8 @@ strstr(const char *in, const char *str)
 {
     char c;
     size_t len;
 {
     char c;
     size_t len;
+    if (!in || !str)
+        return in;
 
     c = *str++;
     if (!c)
 
     c = *str++;
     if (!c)
@@ -1566,6 +1509,26 @@ strstr(const char *in, const char *str)
     return (const char *) (in - 1);
 }
 
     return (const char *) (in - 1);
 }
 
+const void*
+bsearch(const void *key, const void *base0, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
+{
+       const char *base = base0;
+       size_t lim;
+       int cmp;
+       const void *p;
+       for (lim = nmemb; lim != 0; lim >>= 1) {
+               p = base + (lim >> 1) * size;
+               cmp = (*compar)(key, p);
+               if (cmp == 0)
+                       return p;
+               if (cmp > 0) {  /* key > p: move right */
+                       base = (const char *)p + size;
+                       lim--;
+               }               /* else move left */
+       }
+       return (NULL);
+}
+
 /*
  * Runtime and ABI
  */
 /*
  * Runtime and ABI
  */