Loading...
--- libmalloc/libmalloc-166.200.60/src/magazine_rack.c
+++ libmalloc/libmalloc-792.80.2/src/magazine_rack.c
@@ -54,7 +54,8 @@
 	if (num_magazines > 0) {
 		// num_magazines + 1, the [-1] index will become the depot magazine
 		size_t magsize = round_page_quanta(sizeof(magazine_t) * (num_magazines + 1));
-		magazine_t *magazines = mvm_allocate_pages(magsize, 0, MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC);
+		magazine_t *magazines = mvm_allocate_pages(magsize, 0,
+				MALLOC_ADD_GUARD_PAGE_FLAGS|DISABLE_ASLR, VM_MEMORY_MALLOC);
 		if (!magazines) {
 			MALLOC_REPORT_FATAL_ERROR(0, "unable to allocate magazine array");
 		}
@@ -76,9 +77,11 @@
 
 		_malloc_lock_init(&rack->region_lock);
 		_malloc_lock_init(&rack->magazines[DEPOT_MAGAZINE_INDEX].magazine_lock);
+		_malloc_lock_init(&rack->magazines[DEPOT_MAGAZINE_INDEX].magazine_alloc_lock);
 
 		for (int i=0; i < rack->num_magazines; i++) {
 			_malloc_lock_init(&rack->magazines[i].magazine_lock);
+			_malloc_lock_init(&rack->magazines[i].magazine_alloc_lock);
 		}
 	}
 }
@@ -91,7 +94,7 @@
 		if ((rack->region_generation->hashed_regions[i] != HASHRING_OPEN_ENTRY) &&
 			(rack->region_generation->hashed_regions[i] != HASHRING_REGION_DEALLOCATED))
 		{
-			mvm_deallocate_pages(rack->region_generation->hashed_regions[i], region_size, 0);
+			mvm_deallocate_pages(rack->region_generation->hashed_regions[i], region_size, MALLOC_FIX_GUARD_PAGE_FLAGS(rack->debug_flags));
 			rack->region_generation->hashed_regions[i] = HASHRING_REGION_DEALLOCATED;
 		}
 	}
@@ -108,7 +111,7 @@
 
 	if (rack->num_magazines > 0) {
 		size_t size = round_page_quanta(sizeof(magazine_t) * (rack->num_magazines + 1));
-		mvm_deallocate_pages(&rack->magazines[-1], size, MALLOC_ADD_GUARD_PAGES);
+		mvm_deallocate_pages(&rack->magazines[-1], size, MALLOC_ADD_GUARD_PAGE_FLAGS);
 		rack->magazines = NULL;
 	}
 }
@@ -142,10 +145,11 @@
 		rack->region_generation->nextgen->num_regions_allocated = new_size;
 		rack->region_generation->nextgen->num_regions_allocated_shift = new_shift;
 
+		// Ensure everyone sees the advance.
+		OSMemoryBarrier();
+
 		// Throw the switch to atomically advance to the next generation.
 		rack->region_generation = rack->region_generation->nextgen;
-		// Ensure everyone sees the advance.
-		OSMemoryBarrier();
 	}
 
 	// Insert the new region into the hash ring, and update malloc statistics
@@ -157,3 +161,93 @@
 	rack->num_regions++;
 	_malloc_lock_unlock(&rack->region_lock);
 }
+
+bool
+rack_region_remove(rack_t *rack, region_t region, region_trailer_t *trailer)
+{
+	bool rv = true;
+
+	rack_region_lock(rack);
+	rgnhdl_t pSlot = hash_lookup_region_no_lock(
+			rack->region_generation->hashed_regions,
+			rack->region_generation->num_regions_allocated,
+			rack->region_generation->num_regions_allocated_shift,
+			region);
+
+	if ((trailer->dispose_flags & RACK_DISPOSE_DELAY) != 0) {
+		// Still remove this region from the hash table but don't allow the
+		// current caller to deallocate the region until the pressure thread is
+		// done with it.
+		trailer->dispose_flags |= RACK_DISPOSE_NEEDED;
+		rv = false;
+	}
+
+	if (NULL == pSlot) {
+		malloc_zone_error(rack->debug_flags, true,
+				"tiny_free_try_depot_unmap_no_lock hash lookup failed: %p\n",
+				region);
+		rv = false;
+	} else {
+		// Invalidate the hash table entry for this region with
+		// HASHRING_REGION_DEALLOCATED.  Using HASHRING_REGION_DEALLOCATED
+		// preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not.
+		*pSlot = HASHRING_REGION_DEALLOCATED;
+
+		// Atomically increment num_regions_dealloc
+#ifdef __LP64__
+		OSAtomicIncrement64((int64_t *)&rack->num_regions_dealloc);
+#else
+		OSAtomicIncrement32((int32_t *)&rack->num_regions_dealloc);
+#endif
+	}
+
+	rack_region_unlock(rack);
+	return rv;
+}
+
+bool
+rack_region_maybe_dispose(rack_t *rack, region_t region, size_t region_size,
+		region_trailer_t *trailer)
+{
+	bool rv = false;
+	rack_region_lock(rack);
+
+	if ((trailer->dispose_flags & RACK_DISPOSE_NEEDED) != 0) {
+		// We tried to dispose of this region while the pressure thread was
+		// using it, so now that it's finished we can deallocate it now.
+		mvm_deallocate_pages((void *)region, region_size,
+				MALLOC_FIX_GUARD_PAGE_FLAGS(rack->debug_flags));
+		rv = true;
+	} else {
+		trailer->dispose_flags &= ~RACK_DISPOSE_DELAY;
+	}
+	rack_region_unlock(rack);
+	return rv;
+}
+
+
+unsigned int
+rack_get_thread_index(rack_t *rack)
+{
+	mag_index_t index;
+	if (os_likely(_os_cpu_number_override == -1)) {
+		index = _malloc_cpu_number();
+#if CONFIG_MAGAZINE_PER_CLUSTER
+		if (rack->num_magazines == ncpuclusters) {
+			index = _malloc_cpu_cluster_number();
+		}
+#endif // CONFIG_MAGAZINE_PER_CLUSTER
+	} else {
+		index = _os_cpu_number_override;
+#if CONFIG_MAGAZINE_PER_CLUSTER
+		if (rack->num_magazines == ncpuclusters) {
+			index = _malloc_get_cluster_from_cpu(_os_cpu_number_override);
+		}
+#endif // CONFIG_MAGAZINE_PER_CLUSTER
+	}
+#if CONFIG_SZONE_USES_HYPER_SHIFT
+	return index >> hyper_shift;
+#else // CONFIG_SZONE_USES_HYPER_SHIFT
+	return index;
+#endif // CONFIG_SZONE_USES_HYPER_SHIFT
+}