+unsigned int
+cpu_broadcast_xcall(uint32_t *synch,
+ boolean_t self_xcall,
+ broadcastFunc func,
+ void *parm)
+{
+ return cpu_broadcast_xcall_internal(SIGPxcall, synch, self_xcall, func, parm);
+}
+
+struct cpu_broadcast_xcall_simple_data {
+ broadcastFunc func;
+ void* parm;
+ uint32_t sync;
+};
+
+static void
+cpu_broadcast_xcall_simple_cbk(void *parm)
+{
+ struct cpu_broadcast_xcall_simple_data *data = (struct cpu_broadcast_xcall_simple_data*)parm;
+
+ data->func(data->parm);
+
+ if (os_atomic_dec(&data->sync, relaxed) == 0) {
+ thread_wakeup((event_t)&data->sync);
+ }
+}
+
+static unsigned int
+cpu_xcall_simple(boolean_t self_xcall,
+ broadcastFunc func,
+ void *parm,
+ bool immediate)
+{
+ struct cpu_broadcast_xcall_simple_data data = {};
+
+ data.func = func;
+ data.parm = parm;
+
+ return cpu_broadcast_xcall_internal(immediate ? SIGPxcallImm : SIGPxcall, &data.sync, self_xcall, cpu_broadcast_xcall_simple_cbk, &data);
+}
+
+unsigned int
+cpu_broadcast_immediate_xcall(uint32_t *synch,
+ boolean_t self_xcall,
+ broadcastFunc func,
+ void *parm)
+{
+ return cpu_broadcast_xcall_internal(SIGPxcallImm, synch, self_xcall, func, parm);
+}
+
+unsigned int
+cpu_broadcast_xcall_simple(boolean_t self_xcall,
+ broadcastFunc func,
+ void *parm)
+{
+ return cpu_xcall_simple(self_xcall, func, parm, false);
+}
+
+unsigned int
+cpu_broadcast_immediate_xcall_simple(boolean_t self_xcall,
+ broadcastFunc func,
+ void *parm)
+{
+ return cpu_xcall_simple(self_xcall, func, parm, true);
+}
+
+static kern_return_t
+cpu_xcall_internal(unsigned int signal, int cpu_number, broadcastFunc func, void *param)