blob: 03977e3339cab1834951cda06b487f0d43040c77 [file] [log] [blame]
/*
* Copyright (c) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PAS_SEGREGATED_PAGE_GRANULE_USE_COUNT_H
#define PAS_SEGREGATED_PAGE_GRANULE_USE_COUNT_H
#include "pas_utils.h"
PAS_BEGIN_EXTERN_C;
typedef uint8_t pas_segregated_page_granule_use_count;
#define PAS_SEGREGATED_PAGE_GRANULE_DECOMMITTED 255u /* Has to be the max value. */
static PAS_ALWAYS_INLINE void pas_segregated_page_granule_use_count_increment(
pas_segregated_page_granule_use_count* use_count_ptr,
void* arg)
{
pas_segregated_page_granule_use_count use_count;
use_count = *use_count_ptr;
PAS_ASSERT(use_count != PAS_SEGREGATED_PAGE_GRANULE_DECOMMITTED);
use_count++;
PAS_ASSERT(use_count != PAS_SEGREGATED_PAGE_GRANULE_DECOMMITTED);
*use_count_ptr = use_count;
}
static PAS_ALWAYS_INLINE void pas_segregated_page_granule_for_each_use_in_range(
pas_segregated_page_granule_use_count* use_counts,
uintptr_t begin,
uintptr_t end,
uintptr_t page_size,
uintptr_t granule_size,
void (*action)(pas_segregated_page_granule_use_count* use_count, void* arg),
void* arg)
{
uintptr_t index_of_first_granule;
uintptr_t index_of_last_granule;
uintptr_t granule_index;
if (begin == end)
return;
index_of_first_granule = begin / granule_size;
index_of_last_granule = (end - 1) / granule_size;
PAS_ASSERT(index_of_last_granule < page_size / granule_size);
for (granule_index = index_of_first_granule;
granule_index <= index_of_last_granule;
++granule_index)
action(use_counts + granule_index, arg);
}
static PAS_ALWAYS_INLINE void pas_segregated_page_granule_increment_uses_for_range(
pas_segregated_page_granule_use_count* use_counts,
uintptr_t begin,
uintptr_t end,
uintptr_t page_size,
uintptr_t granule_size)
{
pas_segregated_page_granule_for_each_use_in_range(
use_counts, begin, end, page_size, granule_size,
pas_segregated_page_granule_use_count_increment, NULL);
}
PAS_END_EXTERN_C;
#endif /* PAS_SEGREGATED_PAGE_GRANULE_USE_COUNT_H */