Skip to content

Linux port of libdispatch-685 merge #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,6 @@ AC_MSG_CHECKING([what semaphore type to use]);
AS_IF([test "x$have_mach" = "xtrue"],
[AC_DEFINE(USE_MACH_SEM, 1, [Define to use Mach semaphores])
AC_MSG_RESULT([Mach semaphores])],
[test "x$have_futex" = "xtrue"],
[AC_DEFINE(USE_FUTEX_SEM, 1, [Define to use Futex semaphores])
AC_MSG_RESULT([Futex semaphores])],
[test "x$have_sem_init" = "xtrue"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is very good, you should also get rid of all the code guarded with #if USE_FUTEX_SEM that is still around

[AC_DEFINE(USE_POSIX_SEM, 1, [Define to use POSIX semaphores])
AC_MSG_RESULT([POSIX semaphores])],
Expand Down
31 changes: 31 additions & 0 deletions dispatch/dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,37 @@
#ifndef __OSX_AVAILABLE_STARTING
#define __OSX_AVAILABLE_STARTING(x, y)
#endif
#ifndef __OSX_AVAILABLE_BUT_DEPRECATED
#define __OSX_AVAILABLE_BUT_DEPRECATED(...)
#endif
#ifndef __OSX_AVAILABLE_BUT_DEPRECATED_MSG
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(...)
#endif

#ifndef __OSX_AVAILABLE
#define __OSX_AVAILABLE(...)
#endif
#ifndef __IOS_AVAILABLE
#define __IOS_AVAILABLE(...)
#endif
#ifndef __TVOS_AVAILABLE
#define __TVOS_AVAILABLE(...)
#endif
#ifndef __WATCHOS_AVAILABLE
#define __WATCHOS_AVAILABLE(...)
#endif
#ifndef __OSX_DEPRECATED
#define __OSX_DEPRECATED(...)
#endif
#ifndef __IOS_DEPRECATED
#define __IOS_DEPRECATED(...)
#endif
#ifndef __TVOS_DEPRECATED
#define __TVOS_DEPRECATED(...)
#endif
#ifndef __WATCHOS_DEPRECATED
#define __WATCHOS_DEPRECATED(...)
#endif

#define DISPATCH_API_VERSION 20160612

Expand Down
128 changes: 44 additions & 84 deletions os/linux_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,92 +13,60 @@
#ifndef __OS_LINUX_BASE__
#define __OS_LINUX_BASE__

// #include <sys/event.h>
#include <sys/user.h>
#include <sys/param.h>

// marker for hacks we have made to make progress
#define __LINUX_PORT_HDD__ 1

/*
* Stub out defines for some mach types and related macros
*/

typedef uint32_t mach_port_t;

#define MACH_PORT_NULL (0)
#define MACH_PORT_DEAD (-1)

#define EVFILT_MACHPORT (-8)

typedef uint32_t mach_error_t;

typedef uint32_t mach_vm_size_t;

typedef uint32_t mach_msg_return_t;

typedef uintptr_t mach_vm_address_t;

typedef uint32_t dispatch_mach_msg_t;

typedef uint32_t dispatch_mach_t;

typedef uint32_t dispatch_mach_reason_t;

typedef uint32_t voucher_activity_mode_t;

typedef uint32_t voucher_activity_trace_id_t;

typedef uint32_t voucher_activity_id_t;

typedef uint32_t _voucher_activity_buffer_hook_t;;

typedef uint32_t voucher_activity_flag_t;

typedef struct
{
} mach_msg_header_t;


typedef void (*dispatch_mach_handler_function_t)(void*, dispatch_mach_reason_t,
dispatch_mach_msg_t, mach_error_t);

typedef void (*dispatch_mach_msg_destructor_t)(void*);

// Print a warning when an unported code path executes.
#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); } while (0)

/*
* Stub out defines for other missing types
*/

#if __linux__
// we fall back to use kevent
#define kevent64_s kevent
#define kevent64(kq,cl,nc,el,ne,f,to) kevent(kq,cl,nc,el,ne,to)
#if __GNUC__
#define OS_EXPECT(x, v) __builtin_expect((x), (v))
#else
#define OS_EXPECT(x, v) (x)
#endif

// SIZE_T_MAX should not be hardcoded like this here.
#define SIZE_T_MAX (0x7fffffff)
#ifndef os_likely
#define os_likely(x) OS_EXPECT(!!(x), 1)
#endif
#ifndef os_unlikely
#define os_unlikely(x) OS_EXPECT(!!(x), 0)
#endif

// Define to 0 the NOTE_ values that are not present on Linux.
// Revisit this...would it be better to ifdef out the uses instead??
#if __has_feature(assume_nonnull)
#define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
#define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
#else
#define OS_ASSUME_NONNULL_BEGIN
#define OS_ASSUME_NONNULL_END
#endif

// The following values are passed as part of the EVFILT_TIMER requests
#if __has_builtin(__builtin_assume)
#define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
#else
#define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr))
#endif

#define IGNORE_KEVENT64_EXT /* will force the kevent64_s.ext[] to not be used -> leeway ignored */
#if __has_feature(attribute_availability_swift)
// equivalent to __SWIFT_UNAVAILABLE from Availability.h
#define OS_SWIFT_UNAVAILABLE(_msg) \
__attribute__((__availability__(swift, unavailable, message=_msg)))
#else
#define OS_SWIFT_UNAVAILABLE(_msg)
#endif

#define NOTE_SECONDS 0x01
#define NOTE_USECONDS 0x02
#define NOTE_NSECONDS 0x04
#define NOTE_ABSOLUTE 0x08
#define NOTE_CRITICAL 0x10
#define NOTE_BACKGROUND 0x20
#define NOTE_LEEWAY 0x40
#if __has_attribute(swift_private)
# define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__))
#else
# define OS_REFINED_FOR_SWIFT
#endif

// need to catch the following usage if it happens ..
// we simply return '0' as a value probably not correct
#if __has_attribute(swift_name)
# define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name)))
#else
# define OS_SWIFT_NAME(_name)
#endif

#define NOTE_VM_PRESSURE ({LINUX_PORT_ERROR(); 0;})
#define __OS_STRINGIFY(s) #s
#define OS_STRINGIFY(s) __OS_STRINGIFY(s)
#define __OS_CONCAT(x, y) x ## y
#define OS_CONCAT(x, y) __OS_CONCAT(x, y)

/*
* Stub out misc linking and compilation attributes
Expand All @@ -123,12 +91,4 @@ typedef void (*dispatch_mach_msg_destructor_t)(void*);
#endif
#define OS_NOTHROW


// These and similar macros come from Availabilty.h on OS X
// Need a better way to do this long term.
#define __OSX_AVAILABLE_BUT_DEPRECATED(a,b,c,d) //
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(a,b,c,d,msg) //



#endif /* __OS_LINUX_BASE__ */
2 changes: 1 addition & 1 deletion os/voucher_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ dispatch_queue_create_with_accounting_override_voucher(
dispatch_queue_attr_t _Nullable attr,
voucher_t _Nullable voucher);

#ifdef __APPLE__
/*!
* @group Voucher Mach SPI
* SPI intended for clients that need to interact with mach messages or mach
Expand Down Expand Up @@ -444,7 +445,6 @@ OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
voucher_t _Nullable
voucher_create_with_mach_msg(mach_msg_header_t *msg);

#ifdef __APPLE__
/*!
* @group Voucher Persona SPI
* SPI intended for clients that need to interact with personas.
Expand Down
4 changes: 4 additions & 0 deletions src/firehose/firehose_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#ifndef __FIREHOSE_INTERNAL__
#define __FIREHOSE_INTERNAL__

#if OS_FIREHOSE_SPI

// make sure this is defined so that we get MIG_SERVER_DIED when a send once
// notification is sent back because of a crashed server
#ifndef __MigTypeCheck
Expand All @@ -44,4 +46,6 @@
#endif
#include "firehose_inline_internal.h"

#endif // OS_FIREHOSE_SPI

#endif // __FIREHOSE_INTERNAL__
4 changes: 4 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ const struct dispatch_continuation_vtable_s _dispatch_continuation_vtables[] = {
DC_VTABLE_ENTRY(ASYNC_REDIRECT,
.do_kind = "dc-redirect",
.do_invoke = _dispatch_async_redirect_invoke),
#if HAVE_MACH
DC_VTABLE_ENTRY(MACH_SEND_BARRRIER_DRAIN,
.do_kind = "dc-mach-send-drain",
.do_invoke = _dispatch_mach_send_barrier_drain_invoke),
Expand All @@ -495,6 +496,7 @@ const struct dispatch_continuation_vtable_s _dispatch_continuation_vtables[] = {
DC_VTABLE_ENTRY(MACH_RECV_BARRIER,
.do_kind = "dc-mach-recv-barrier",
.do_invoke = _dispatch_mach_barrier_invoke),
#endif
#if HAVE_PTHREAD_WORKQUEUE_QOS
DC_VTABLE_ENTRY(OVERRIDE_STEALING,
.do_kind = "dc-override-stealing",
Expand Down Expand Up @@ -1195,7 +1197,9 @@ dispatch_source_type_readwrite_init(dispatch_source_t ds,
{
ds->ds_is_level = true;
// bypass kernel check for device kqueue support rdar://19004921
#ifdef NOTE_LOWAT
ds->ds_dkev->dk_kevent.fflags = NOTE_LOWAT;
#endif
ds->ds_dkev->dk_kevent.data = 1;
}

Expand Down
20 changes: 11 additions & 9 deletions src/inline_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ _dispatch_queue_drain_try_lock(dispatch_queue_t dq,
uint64_t pending_barrier_width =
(dq->dq_width - 1) * DISPATCH_QUEUE_WIDTH_INTERVAL;
uint64_t xor_owner_and_set_full_width =
_dispatch_thread_port() | DISPATCH_QUEUE_WIDTH_FULL_BIT;
_dispatch_tid_self() | DISPATCH_QUEUE_WIDTH_FULL_BIT;
uint64_t clear_enqueued_bit, old_state, new_state;

if (flags & DISPATCH_INVOKE_STEALING) {
Expand Down Expand Up @@ -1041,7 +1041,7 @@ static inline bool
_dispatch_queue_try_acquire_barrier_sync(dispatch_queue_t dq)
{
uint64_t value = DISPATCH_QUEUE_WIDTH_FULL_BIT | DISPATCH_QUEUE_IN_BARRIER;
value |= _dispatch_thread_port();
value |= _dispatch_tid_self();

return os_atomic_cmpxchg2o(dq, dq_state,
DISPATCH_QUEUE_STATE_INIT_VALUE(dq->dq_width), value, acquire);
Expand Down Expand Up @@ -1577,7 +1577,7 @@ _dispatch_root_queue_identity_assume(struct _dispatch_identity_s *di,
if (!pp) pp = di->old_pri;
if ((pp & _PTHREAD_PRIORITY_QOS_CLASS_MASK) >
(assumed_rq->dq_priority & _PTHREAD_PRIORITY_QOS_CLASS_MASK)) {
_dispatch_wqthread_override_start(_dispatch_thread_port(), pp);
_dispatch_wqthread_override_start(_dispatch_tid_self(), pp);
// Ensure that the root queue sees that this thread was overridden.
_dispatch_set_defaultpriority_override();
}
Expand Down Expand Up @@ -1630,7 +1630,7 @@ _dispatch_queue_class_invoke(dispatch_object_t dou,
drain_pending_barrier:
if (overriding) {
_dispatch_object_debug(dq, "stolen onto thread 0x%x, 0x%lx",
_dispatch_thread_port(), _dispatch_get_defaultpriority());
_dispatch_tid_self(), _dispatch_get_defaultpriority());
_dispatch_root_queue_identity_assume(&di, 0, 0);
}

Expand All @@ -1640,7 +1640,7 @@ _dispatch_queue_class_invoke(dispatch_object_t dou,
old_dp = _dispatch_set_defaultpriority(dq->dq_priority, &dp);
op = dq->dq_override;
if (op > (dp & _PTHREAD_PRIORITY_QOS_CLASS_MASK)) {
_dispatch_wqthread_override_start(_dispatch_thread_port(), op);
_dispatch_wqthread_override_start(_dispatch_tid_self(), op);
// Ensure that the root queue sees that this thread was overridden.
_dispatch_set_defaultpriority_override();
}
Expand Down Expand Up @@ -1825,7 +1825,7 @@ _dispatch_queue_set_bound_thread(dispatch_queue_t dq)
{
// Tag thread-bound queues with the owning thread
dispatch_assert(_dispatch_queue_is_thread_bound(dq));
mach_port_t old_owner, self = _dispatch_thread_port();
mach_port_t old_owner, self = _dispatch_tid_self();
uint64_t dq_state = os_atomic_or_orig2o(dq, dq_state, self, relaxed);
if (unlikely(old_owner = _dq_state_drain_owner(dq_state))) {
DISPATCH_INTERNAL_CRASH(old_owner, "Queue bound twice");
Expand Down Expand Up @@ -1888,7 +1888,7 @@ _dispatch_reset_defaultpriority(pthread_priority_t pp)
pp |= old_pp & _PTHREAD_PRIORITY_OVERRIDE_FLAG;
_dispatch_thread_setspecific(dispatch_defaultpriority_key, (void*)pp);
#else
(void)priority;
(void)pp;
#endif
}

Expand Down Expand Up @@ -1994,7 +1994,7 @@ _dispatch_priority_adopt(pthread_priority_t pp, unsigned long flags)
return defaultpri;
}
#else
(void)priority; (void)flags;
(void)pp; (void)flags;
return 0;
#endif
}
Expand Down Expand Up @@ -2037,6 +2037,7 @@ static inline pthread_priority_t
_dispatch_priority_compute_update(pthread_priority_t pp,
_dispatch_thread_set_self_t flags)
{
#if HAVE_PTHREAD_WORKQUEUE_QOS
dispatch_assert(pp != DISPATCH_NO_PRIORITY);
if (!_dispatch_set_qos_class_enabled) return 0;
// the priority in _dispatch_get_priority() only tracks manager-ness
Expand All @@ -2047,7 +2048,6 @@ _dispatch_priority_compute_update(pthread_priority_t pp,
// the manager bit is invalid input, but we keep it to get meaningful
// assertions in _dispatch_set_priority_and_voucher_slow()
pp &= _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG | ~_PTHREAD_PRIORITY_FLAGS_MASK;
#if HAVE_PTHREAD_WORKQUEUE_QOS
pthread_priority_t cur_priority = _dispatch_get_priority();
pthread_priority_t unbind = _PTHREAD_PRIORITY_NEEDS_UNBIND_FLAG;
pthread_priority_t overcommit = _PTHREAD_PRIORITY_OVERCOMMIT_FLAG;
Expand All @@ -2064,6 +2064,8 @@ _dispatch_priority_compute_update(pthread_priority_t pp,
cur_priority &= ~overcommit;
}
if (unlikely(pp != cur_priority)) return pp;
#else
(void)pp; (void)flags;
#endif
return 0;
}
Expand Down
20 changes: 15 additions & 5 deletions src/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@
#include <dispatch/io.h>
#endif

#define DISPATCH_PURE_C (!defined(__OBJC__) && !defined(__cplusplus))
#if defined(__OBJC__) || defined(__cplusplus)
#define DISPATCH_PURE_C 0
#else
#define DISPATCH_PURE_C 1
#endif

/* private.h must be included last to avoid picking up installed headers. */
#include "os/object_private.h"
Expand Down Expand Up @@ -256,10 +260,6 @@ DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void);
#endif
#include <limits.h>
#include <search.h>
#if USE_FUTEX_SEM
#include <sys/syscall.h>
#include <linux/futex.h>
#endif
#if USE_POSIX_SEM
#include <semaphore.h>
#endif
Expand Down Expand Up @@ -939,6 +939,16 @@ _dispatch_ktrace_impl(uint32_t code, uint64_t a, uint64_t b,
#define VOUCHER_USE_BANK_AUTOREDEEM 1
#endif

#if OS_FIREHOSE_SPI
#include <firehose/private.h>
#else
typedef uint64_t firehose_activity_id_t;
typedef uint64_t firehose_tracepoint_id_t;
typedef unsigned long firehose_activity_flags_t;
typedef uint8_t firehose_stream_t;
typedef void * voucher_activity_hooks_t;
#endif

#if !VOUCHER_USE_MACH_VOUCHER || \
!__has_include(<voucher/ipc_pthread_priority_types.h>) || \
!DISPATCH_HOST_SUPPORTS_OSX(101200)
Expand Down
Loading