workgroup_internal.h [plain text]
#ifndef __OS_WORKGROUP_INTERNAL__
#define __OS_WORKGROUP_INTERNAL__
#include <stdint.h>
#include <sys/work_interval.h>
#include <sys/types.h>
#include <os/lock.h>
void _os_workgroup_xref_dispose(os_workgroup_t wg);
void _os_workgroup_dispose(os_workgroup_t wg);
void _os_workgroup_interval_xref_dispose(os_workgroup_interval_t wgi);
void _os_workgroup_interval_dispose(os_workgroup_interval_t wgi);
void _os_workgroup_debug(os_workgroup_t wg, char *buf, size_t size);
extern pthread_key_t _os_workgroup_key;
void _os_workgroup_tsd_cleanup(void *ctxt);
typedef uint16_t os_workgroup_type_t;
#define OS_WORKGROUP_TYPE_DEFAULT 0x0
#define OS_WORKGROUP_TYPE_PARALLEL 0x40
#define _OS_WORKGROUP_ATTR_RESOLVED_INIT 0x782618DA
struct os_workgroup_attr_s {
uint32_t sig;
uint32_t wg_attr_flags;
os_workgroup_type_t wg_type;
uint16_t empty;
uint32_t reserved[13];
};
#define _OS_WORKGROUP_JOIN_TOKEN_SIG_INIT 0x4D5F5A58
struct os_workgroup_join_token_s {
uint32_t sig;
mach_port_t thread;
os_workgroup_t old_wg;
os_workgroup_t new_wg;
uint64_t reserved[2];
};
struct os_workgroup_interval_data_s {
uint32_t sig;
uint32_t reserved[14];
};
typedef struct os_workgroup_arena_s {
void *client_arena;
os_workgroup_working_arena_destructor_t destructor;
uint32_t max_workers;
uint32_t next_worker_index;
mach_port_t arena_indices[0];
} *os_workgroup_arena_t;
#define OS_WORKGROUP_OWNER (1 << 0)
#define OS_WORKGROUP_CANCELED (1 << 1)
#define OS_WORKGROUP_LABEL_NEEDS_FREE (1 << 2)
#define OS_WORKGROUP_INTERVAL_STARTED (1 << 3)
#if !defined(__LP64__) || (__LP64_ && !defined(__arm64__))
typedef uint64_t _os_workgroup_atomic_flags;
typedef uint16_t os_joined_cnt_t;
#define OS_WORKGROUP_JOINED_COUNT_SHIFT 48
#define OS_WORKGROUP_JOINED_COUNT_MASK (((uint64_t) 0xffff) << OS_WORKGROUP_JOINED_COUNT_SHIFT)
#define OS_WORKGROUP_ARENA_MASK 0xffffffffull
#define OS_WORKGROUP_HEADER_INTERNAL \
DISPATCH_UNION_LE(_os_workgroup_atomic_flags volatile wg_atomic_flags, \
os_workgroup_arena_t wg_arena, \
os_workgroup_type_t wg_type, \
os_joined_cnt_t joined_cnt \
)
#else
typedef __uint128_t _os_workgroup_atomic_flags;
typedef uint32_t os_joined_cnt_t;
#define OS_WORKGROUP_JOINED_COUNT_SHIFT 96
#define OS_WORKGROUP_JOINED_COUNT_MASK (((__uint128_t) 0xffffffff) << OS_WORKGROUP_JOINED_COUNT_SHIFT)
#define OS_WORKGROUP_ARENA_MASK 0xffffffffffffffffull
#define OS_WORKGROUP_HEADER_INTERNAL \
DISPATCH_UNION_LE(_os_workgroup_atomic_flags volatile wg_atomic_flags, \
os_workgroup_arena_t wg_arena, \
os_workgroup_type_t wg_type, \
const uint16_t empty, \
os_joined_cnt_t joined_cnt \
)
#endif
static inline os_joined_cnt_t
_wg_joined_cnt(_os_workgroup_atomic_flags wgaf)
{
return (os_joined_cnt_t) (((wgaf & OS_WORKGROUP_JOINED_COUNT_MASK)) >> OS_WORKGROUP_JOINED_COUNT_SHIFT);
}
static inline os_workgroup_arena_t
_wg_arena(_os_workgroup_atomic_flags wgaf)
{
return (os_workgroup_arena_t) (wgaf & OS_WORKGROUP_ARENA_MASK);
}
#define OS_WORKGROUP_HEADER \
struct _os_object_s _as_os_obj[0]; \
OS_OBJECT_STRUCT_HEADER(workgroup); \
const char *name; \
uint64_t volatile wg_state; \
union { \
work_interval_t wi; \
mach_port_t port; \
}; \
OS_WORKGROUP_HEADER_INTERNAL;
struct os_workgroup_s {
OS_WORKGROUP_HEADER
};
struct os_workgroup_interval_s {
struct os_workgroup_s _as_wg[0];
OS_WORKGROUP_HEADER
os_clockid_t clock;
os_unfair_lock wii_lock;
work_interval_instance_t wii;
};
struct os_workgroup_parallel_s {
OS_WORKGROUP_HEADER
};
_Static_assert(sizeof(struct os_workgroup_attr_s) == sizeof(struct os_workgroup_attr_opaque_s),
"Incorrect size of workgroup attribute structure");
_Static_assert(sizeof(struct os_workgroup_join_token_s) == sizeof(struct os_workgroup_join_token_opaque_s),
"Incorrect size of workgroup join token structure");
_Static_assert(sizeof(struct os_workgroup_interval_data_s) == sizeof(struct os_workgroup_interval_data_opaque_s),
"Incorrect size of workgroup interval data structure");
#endif