#ifndef _SYS_COALITION_H_
#define _SYS_COALITION_H_
-#include <sys/cdefs.h>
-#include <Availability.h>
#include <stdint.h>
+#include <sys/cdefs.h>
#include <sys/types.h>
+#include <mach/coalition.h>
+
__BEGIN_DECLS
#ifndef KERNEL
int coalition_terminate(uint64_t cid, uint32_t flags);
int coalition_reap(uint64_t cid, uint32_t flags);
-/* This struct is also defined in osfmk/kern/coalition.h. Keep in sync. */
-struct coalition_resource_usage {
- uint64_t tasks_started;
- uint64_t tasks_exited;
- uint64_t time_nonempty;
- uint64_t cpu_time;
- uint64_t interrupt_wakeups;
- uint64_t platform_idle_wakeups;
- uint64_t bytesread;
- uint64_t byteswritten;
- uint64_t gpu_time;
-};
-
/* Wrappers around __coalition_info syscall (with proper struct types) */
int coalition_info_resource_usage(uint64_t cid, struct coalition_resource_usage *cru, size_t sz);
-#endif /* KERNEL */
+#else /* KERNEL */
-/* Flags shared by userspace and xnu */
+#if CONFIG_COALITIONS
+/* in-kernel BSD interfaces */
-#define COALITION_CREATE_FLAG_PRIVILEGED ((uint32_t)0x1)
+/*
+ * coalition_id:
+ * Get the unique 64-bit identifier associated with the given coalition
+ */
+uint64_t coalition_id(coalition_t coal);
-#define COALITION_CREATE_FLAG_MASK ((uint32_t)0x1)
-#ifdef PRIVATE
-/* Flavors shared by only xnu + Libsyscall */
+/*
+ * coalitions_get_list:
+ * Get a list of coalitions as procinfo_coalinfo structures
+ *
+ * This interface is primarily to support libproc.
+ *
+ * Parameters:
+ * type : The COALITION_TYPE of the coalitions to investigate.
+ * Valid types can be found in <mach/coalition.h>
+ * coal_list : Pointer to an array of procinfo_coalinfo structures
+ * that will be filled with information about each
+ * coalition whose type matches 'type'
+ * NOTE: This can be NULL to perform a simple query of
+ * the total number of coalitions.
+ * list_sz : The size (in number of structures) of 'coal_list'
+ *
+ * Returns: 0 if no coalitions matching 'type' are found
+ * Otherwise: the number of coalitions whose type matches
+ * the 'type' parameter (all coalitions if type == -1)
+ */
+extern int coalitions_get_list(int type, struct procinfo_coalinfo *coal_list, int list_sz);
-/* Syscall flavors */
-#define COALITION_OP_CREATE 1
-#define COALITION_OP_TERMINATE 2
-#define COALITION_OP_REAP 3
-/* coalition_info flavors */
-#define COALITION_INFO_RESOURCE_USAGE 1
+/*
+ * coalition_is_leader:
+ * Determine if a task is a coalition leader.
+ *
+ * Parameters:
+ * task : The task to investigate
+ * coal_type : The COALITION_TYPE of the coalition to investigate.
+ * Valid types can be found in <mach/coalition.h>
+ * coal : If 'task' is a valid task, and is a member of a coalition
+ * of type 'coal_type', then 'coal' will be filled in with
+ * the corresponding coalition_t object.
+ * NOTE: This will be filled in whether or not the 'task' is
+ * a leader in the coalition. However, if 'task' is
+ * not a member of a coalition of type 'coal_type' then
+ * 'coal' will be filled in with COALITION_NULL.
+ * NOTE: This can be NULL
+ *
+ * Returns: TRUE if 'task' is a coalition leader, FALSE otherwise.
+ */
+extern boolean_t coalition_is_leader(task_t task, int coal_type, coalition_t *coal);
-#endif /* PRIVATE */
+/*
+ * coalition_get_task_count:
+ * Sum up the number of tasks in the given coalition
+ *
+ * Parameters:
+ * coal : The coalition to investigate
+ *
+ * Returns: The number of tasks in the coalition
+ */
+extern int coalition_get_task_count(coalition_t coal);
+
+/*
+ * coalition_get_page_count:
+ * Sum up the page count for each task in the coalition specified by 'coal'
+ *
+ * Parameters:
+ * coal : The coalition to investigate
+ * ntasks : If non-NULL, this will be filled in with the number of
+ * tasks in the coalition.
+ *
+ * Returns: The sum of all pages used by all members of the coalition
+ */
+extern uint64_t coalition_get_page_count(coalition_t coal, int *ntasks);
+
+/*
+ * coalition_get_pid_list:
+ * Gather a list of constituent PIDs of tasks within a coalition playing a
+ * given role.
+ *
+ * Parameters:
+ * coal : The coalition to investigate
+ * rolemask : The set of coalition task roles used to filter the list
+ * of PIDs returned in 'pid_list'. Roles can be combined
+ * using the COALITION_ROLEMASK_* tokens found in
+ * <mach/coalition.h>. Each PID returned is guaranteed to
+ * be tagged with one of the task roles specified by this
+ * mask.
+ * sort_order : The order in which the returned PIDs should be sorted
+ * by default this is in descending page count.
+ * pid_list : Pointer to an array of PIDs that will be filled with
+ * members of the coalition tagged with the given 'taskrole'
+ * list_sz : The size (in number of PIDs) of 'pid_list'
+ *
+ * Note:
+ * This function will return the list of PIDs in a sorted order. By default
+ * the PIDs will be sorted by task page count in descending order. In the
+ * future it may be possible for user space to specify a level of importance
+ * for each coalition member. If there is a user space specified importance,
+ * then the list of PIDs returned will be sorted in _ascending_ importance,
+ * i.e., pid_list[0] will be the least important task (or the largest consumer
+ * of memory). The desired sort order can be specified using the
+ * COALITION_SORT_* definitions in osfmk/mach/coalition.h
+ *
+ * It is also possible to return an unsorted list of PIDs using the special
+ * sort type 'COALITION_SORT_NOSORT'
+ *
+ * Returns: < 0 on ERROR
+ * 0 if 'coal' contains no tasks whose role is 'taskrole'
+ * (or if the coalition is being deallocated)
+ * Otherwise: the number of PIDs in the coalition whose role is
+ * 'taskrole'. NOTE: This may be larger or smaller than
+ * the 'pid_list' array.
+ *
+ */
+extern int coalition_get_pid_list(coalition_t coal, uint32_t rolemask,
+ int sort_order, int *pid_list, int list_sz);
+
+#else /* !CONFIG_COALITIONS */
+static inline uint64_t coalition_id(__unused coalition_t coal)
+{
+ return 0;
+}
+
+static inline int coalitions_get_list(__unused int type,
+ __unused struct procinfo_coalinfo *coal_list,
+ __unused int list_sz)
+{
+ return 0;
+}
+
+static inline boolean_t coalition_is_leader(__unused task_t task,
+ __unused int coal_type,
+ coalition_t *coal)
+{
+ *coal = COALITION_NULL;
+ return FALSE;
+}
+
+static inline int coalition_get_task_count(__unused coalition_t coal)
+{
+ return 0;
+}
+
+static inline uint64_t coalition_get_page_count(__unused coalition_t coal,
+ __unused int *ntasks)
+{
+ return 0;
+}
+
+static inline int coalition_get_pid_list(__unused coalition_t coal,
+ __unused uint32_t rolemask,
+ __unused int sort_order,
+ __unused int *pid_list,
+ __unused int list_sz)
+{
+ return 0;
+}
+#endif
+
+#endif /* KERNEL */
__END_DECLS