* the "shared_region" EMM.
*/
typedef struct shared_region_pager {
- struct memory_object srp_header; /* mandatory generic header */
+ struct memory_object srp_header; /* mandatory generic header */
/* pager-specific data */
queue_chain_t srp_queue; /* next & prev pagers */
- uint32_t srp_ref_count; /* active uses */
+#if MEMORY_OBJECT_HAS_REFCOUNT
+#define srp_ref_count srp_header.mo_ref
+#else
+ os_ref_atomic_t srp_ref_count; /* active uses */
+#endif
bool srp_is_mapped; /* has active mappings */
bool srp_is_ready; /* is this pager ready? */
vm_object_t srp_backing_object; /* VM object for shared cache */
pager = shared_region_pager_lookup(mem_obj);
assert(pager->srp_is_ready);
- assert(pager->srp_ref_count > 1); /* pager is alive */
+ assert(os_ref_get_count_raw(&pager->srp_ref_count) > 1); /* pager is alive */
assert(pager->srp_is_mapped); /* pager is mapped */
PAGER_DEBUG(PAGER_PAGEIN, ("shared_region_pager_data_request: %p, %llx, %x, %x, pager %p\n", mem_obj, offset, length, protection_required, pager));
retval = kr;
goto done;
}
- dst_object = mo_control->moc_object;
+ dst_object = memory_object_control_to_vm_object(mo_control);
assert(dst_object != VM_OBJECT_NULL);
/*
pager = shared_region_pager_lookup(mem_obj);
lck_mtx_lock(&shared_region_pager_lock);
- assert(pager->srp_ref_count > 0);
- pager->srp_ref_count++;
+ os_ref_retain_locked_raw(&pager->srp_ref_count, NULL);
lck_mtx_unlock(&shared_region_pager_lock);
}
{
assert(pager->srp_is_ready);
assert(!pager->srp_is_mapped);
- assert(pager->srp_ref_count == 1);
+ assert(os_ref_get_count_raw(&pager->srp_ref_count) == 1);
if (pager->srp_backing_object != VM_OBJECT_NULL) {
vm_object_deallocate(pager->srp_backing_object);
{
boolean_t needs_trimming;
int count_unmapped;
+ os_ref_count_t ref_count;
if (!locked) {
lck_mtx_lock(&shared_region_pager_lock);
needs_trimming = (count_unmapped > shared_region_pager_cache_limit);
/* drop a reference on this pager */
- assert(pager->srp_ref_count > 0);
- pager->srp_ref_count--;
+ ref_count = os_ref_release_locked_raw(&pager->srp_ref_count, NULL);
- if (pager->srp_ref_count == 1) {
+ if (ref_count == 1) {
/*
* Only the "named" reference is left, which means that
* no one is really holding on to this pager anymore.
/* the pager is all ours: no need for the lock now */
lck_mtx_unlock(&shared_region_pager_lock);
shared_region_pager_terminate_internal(pager);
- } else if (pager->srp_ref_count == 0) {
+ } else if (ref_count == 0) {
/*
* Dropped the existence reference; the memory object has
* been terminated. Do some final cleanup and release the
lck_mtx_lock(&shared_region_pager_lock);
assert(pager->srp_is_ready);
- assert(pager->srp_ref_count > 0); /* pager is alive */
+ assert(os_ref_get_count_raw(&pager->srp_ref_count) > 0); /* pager is alive */
if (!pager->srp_is_mapped) {
pager->srp_is_mapped = TRUE;
- pager->srp_ref_count++;
+ os_ref_retain_locked_raw(&pager->srp_ref_count, NULL);
shared_region_pager_count_mapped++;
}
lck_mtx_unlock(&shared_region_pager_lock);
assert(mem_obj->mo_pager_ops == &shared_region_pager_ops);
pager = (shared_region_pager_t)(uintptr_t) mem_obj;
- assert(pager->srp_ref_count > 0);
+ assert(os_ref_get_count_raw(&pager->srp_ref_count) > 0);
return pager;
}
pager->srp_header.mo_control = MEMORY_OBJECT_CONTROL_NULL;
pager->srp_is_ready = FALSE;/* not ready until it has a "name" */
- pager->srp_ref_count = 1; /* existence reference (for the cache) */
- pager->srp_ref_count++; /* for the caller */
+ /* existence reference (for the cache) + 1 for the caller */
+ os_ref_init_count_raw(&pager->srp_ref_count, NULL, 2);
pager->srp_is_mapped = FALSE;
pager->srp_backing_object = backing_object;
pager->srp_backing_offset = backing_offset;
if (memcmp(si->si_slide_info_entry, slide_info->si_slide_info_entry, si->si_slide_info_size) != 0) {
continue;
}
- ++pager->srp_ref_count; /* the caller expects a reference on this */
+ /* the caller expects a reference on this */
+ os_ref_retain_locked_raw(&pager->srp_ref_count, NULL);
lck_mtx_unlock(&shared_region_pager_lock);
return (memory_object_t)pager;
}
/* get prev elt before we dequeue */
prev_pager = (shared_region_pager_t)queue_prev(&pager->srp_queue);
- if (pager->srp_ref_count == 2 &&
+ if (os_ref_get_count_raw(&pager->srp_ref_count) == 2 &&
pager->srp_is_ready &&
!pager->srp_is_mapped) {
/* this pager can be trimmed */
srp_queue);
pager->srp_queue.next = NULL;
pager->srp_queue.prev = NULL;
- assert(pager->srp_ref_count == 2);
+ assert(os_ref_get_count_raw(&pager->srp_ref_count) == 2);
/*
* We can't call deallocate_internal() because the pager
* has already been dequeued, but we still need to remove
* a reference.
*/
- pager->srp_ref_count--;
+ (void)os_ref_release_locked_raw(&pager->srp_ref_count, NULL);
shared_region_pager_terminate_internal(pager);
}
}