#endif
#endif
-#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090
-#undef DISPATCH_USE_NANOZONE
-#define DISPATCH_USE_NANOZONE 0
-#endif
#ifndef DISPATCH_USE_NANOZONE
-#if TARGET_OS_MAC && defined(__LP64__) && \
- (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 || \
- __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000)
+#if TARGET_OS_MAC && defined(__LP64__)
#define DISPATCH_USE_NANOZONE 1
#endif
#endif
#if DISPATCH_ALLOCATOR
// Configuration here!
-#define NUM_CPU _dispatch_hw_config.cc_max_logical
+#define NUM_CPU dispatch_hw_config(logical_cpus)
#define MAGAZINES_PER_HEAP (NUM_CPU)
// Do you care about compaction or performance?
#define PACK_FIRST_PAGE_WITH_CONTINUATIONS 0
#endif
+#ifndef PAGE_MAX_SIZE
+#define PAGE_MAX_SIZE PAGE_SIZE
+#endif
+#ifndef PAGE_MAX_MASK
+#define PAGE_MAX_MASK PAGE_MASK
+#endif
+#define DISPATCH_ALLOCATOR_PAGE_SIZE PAGE_MAX_SIZE
+#define DISPATCH_ALLOCATOR_PAGE_MASK PAGE_MAX_MASK
+
+
#if TARGET_OS_EMBEDDED
#define PAGES_PER_MAGAZINE 64
#else
#endif
// Use the largest type your platform is comfortable doing atomic ops with.
-#if defined(__x86_64__) // TODO: rdar://11477843
+// TODO: rdar://11477843
typedef unsigned long bitmap_t;
+#if defined(__LP64__)
#define BYTES_PER_BITMAP 8
#else
-typedef uint32_t bitmap_t;
#define BYTES_PER_BITMAP 4
#endif
#define CONTINUATIONS_PER_BITMAP (BYTES_PER_BITMAP * 8)
#define BITMAPS_PER_SUPERMAP (BYTES_PER_SUPERMAP * 8)
-#define BYTES_PER_MAGAZINE (PAGES_PER_MAGAZINE * PAGE_SIZE)
+#define BYTES_PER_MAGAZINE (PAGES_PER_MAGAZINE * DISPATCH_ALLOCATOR_PAGE_SIZE)
#define CONSUMED_BYTES_PER_BITMAP (BYTES_PER_BITMAP + \
(DISPATCH_CONTINUATION_SIZE * CONTINUATIONS_PER_BITMAP))
#define BYTES_PER_HEAP (BYTES_PER_MAGAZINE * MAGAZINES_PER_HEAP)
-#define BYTES_PER_PAGE PAGE_SIZE
+#define BYTES_PER_PAGE DISPATCH_ALLOCATOR_PAGE_SIZE
#define CONTINUATIONS_PER_PAGE (BYTES_PER_PAGE / DISPATCH_CONTINUATION_SIZE)
#define BITMAPS_PER_PAGE (CONTINUATIONS_PER_PAGE / CONTINUATIONS_PER_BITMAP)
#define HEAP_MASK (~(uintptr_t)(BYTES_PER_HEAP - 1))
#define MAGAZINE_MASK (~(uintptr_t)(BYTES_PER_MAGAZINE - 1))
+// this will round up such that first_bitmap_in_same_page() can mask the address
+// of a bitmap_t in the maps to obtain the first bitmap for that same page
+#define ROUND_UP_TO_BITMAP_ALIGNMENT(x) \
+ (((x) + ((BITMAPS_PER_PAGE * BYTES_PER_BITMAP) - 1u)) & \
+ ~((BITMAPS_PER_PAGE * BYTES_PER_BITMAP) - 1u))
+// Since these are both powers of two, we end up with not only the max alignment,
+// but happily the least common multiple, which will be the greater of the two.
+#define ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(x) (ROUND_UP_TO_CONTINUATION_SIZE(ROUND_UP_TO_BITMAP_ALIGNMENT(x)))
+#define PADDING_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(x) (ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(x) - (x))
+
#define PADDING_TO_CONTINUATION_SIZE(x) (ROUND_UP_TO_CONTINUATION_SIZE(x) - (x))
#if defined(__LP64__)
// header is expected to end on supermap's required alignment
#define HEADER_TO_SUPERMAPS_PADDING 0
-#define SUPERMAPS_TO_MAPS_PADDING (PADDING_TO_CONTINUATION_SIZE( \
+// we want to align the maps to a continuation size, but we must also have proper padding
+// so that we can perform first_bitmap_in_same_page()
+#define SUPERMAPS_TO_MAPS_PADDING (PADDING_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE( \
SIZEOF_SUPERMAPS + HEADER_TO_SUPERMAPS_PADDING + SIZEOF_HEADER))
+
#define MAPS_TO_FPMAPS_PADDING (PADDING_TO_CONTINUATION_SIZE(SIZEOF_MAPS))
#define BYTES_LEFT_IN_FIRST_PAGE (BYTES_PER_PAGE - \
(BYTES_LEFT_IN_FIRST_PAGE / CONSUMED_BYTES_PER_BITMAP)
#define REMAINDER_IN_FIRST_PAGE (BYTES_LEFT_IN_FIRST_PAGE - \
(FULL_BITMAPS_IN_FIRST_PAGE * CONSUMED_BYTES_PER_BITMAP) - \
- (FULL_BITMAPS_IN_FIRST_PAGE ? 0 : ROUND_UP_TO_CONTINUATION_SIZE(BYTES_PER_BITMAP)))
+ (FULL_BITMAPS_IN_FIRST_PAGE ? 0 : \
+ ROUND_UP_TO_CONTINUATION_SIZE(BYTES_PER_BITMAP)))
#define REMAINDERED_CONTINUATIONS_IN_FIRST_PAGE \
(REMAINDER_IN_FIRST_PAGE / DISPATCH_CONTINUATION_SIZE)
// Link to the next heap in the chain. Only used in magazine 0's header
dispatch_heap_t dh_next;
- // Points to the first bitmap in the page where this CPU succesfully
+ // Points to the first bitmap in the page where this CPU successfully
// allocated a continuation last time. Only used in the first heap.
bitmap_t *last_found_page;
};