HelenOS sources

root/kernel/generic/src/cpu/cpu_mask.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cpu_mask_size
  2. cpu_mask_count
  3. cpu_mask_active
  4. cpu_mask_all
  5. cpu_mask_none
  6. cpu_mask_set
  7. cpu_mask_reset
  8. cpu_mask_is_set
  9. cpu_mask_is_none

/*
 * Copyright (c) 2012 Adam Hraska
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - 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.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
 */

/** @addtogroup kernel_generic
 * @{
 */

/**
 * @file
 * @brief CPU mask manipulation functions.
 */
#include <assert.h>
#include <cpu/cpu_mask.h>
#include <cpu.h>
#include <config.h>

static const size_t word_size = sizeof(unsigned int);
static const size_t word_bit_cnt = 8 * sizeof(unsigned int);

/** Returns the size of cpu_mask_t for the detected number of cpus in bytes. */
size_t cpu_mask_size(void)
{
        size_t word_cnt = (config.cpu_count + word_bit_cnt - 1) / word_bit_cnt;
        return word_cnt * word_size;
}

/** Add first cpu_cnt cpus to the mask, ie sets the first cpu_cnt bits. */
static void cpu_mask_count(cpu_mask_t *cpus, size_t cpu_cnt)
{
        assert(NULL != cpus);
        assert(cpu_cnt <= config.cpu_count);

        for (size_t active_word = 0;
            (active_word + 1) * word_bit_cnt <= cpu_cnt;
            ++active_word) {
                /* Set all bits in the cell/word. */
                cpus->mask[active_word] = -1;
        }

        size_t remaining_bits = (cpu_cnt % word_bit_cnt);
        if (0 < remaining_bits) {
                /* Set lower remaining_bits of the last word. */
                cpus->mask[cpu_cnt / word_bit_cnt] = (1 << remaining_bits) - 1;
        }
}

/** Sets bits corresponding to the active cpus, ie the first
 * config.cpu_active cpus.
 */
void cpu_mask_active(cpu_mask_t *cpus)
{
        cpu_mask_none(cpus);
        cpu_mask_count(cpus, config.cpu_active);
}

/** Sets bits for all cpus of the mask. */
void cpu_mask_all(cpu_mask_t *cpus)
{
        cpu_mask_count(cpus, config.cpu_count);
}

/** Resets/removes all bits. */
void cpu_mask_none(cpu_mask_t *cpus)
{
        assert(cpus);

        size_t word_cnt = cpu_mask_size() / word_size;

        for (size_t word = 0; word < word_cnt; ++word) {
                cpus->mask[word] = 0;
        }
}

/** Sets the bit corresponding to cpu_id to true. */
void cpu_mask_set(cpu_mask_t *cpus, unsigned int cpu_id)
{
        size_t word = cpu_id / word_bit_cnt;
        size_t word_pos = cpu_id % word_bit_cnt;

        cpus->mask[word] |= (1U << word_pos);
}

/** Resets the bit corresponding to cpu_id to false. */
void cpu_mask_reset(cpu_mask_t *cpus, unsigned int cpu_id)
{
        size_t word = cpu_id / word_bit_cnt;
        size_t word_pos = cpu_id % word_bit_cnt;

        cpus->mask[word] &= ~(1U << word_pos);
}

/** Returns true if the bit corresponding to cpu_id is set. */
bool cpu_mask_is_set(cpu_mask_t *cpus, unsigned int cpu_id)
{
        size_t word = cpu_id / word_bit_cnt;
        size_t word_pos = cpu_id % word_bit_cnt;

        return 0 != (cpus->mask[word] & (1U << word_pos));
}

/** Returns true if no bits are set. */
bool cpu_mask_is_none(cpu_mask_t *cpus)
{
        size_t word_cnt = cpu_mask_size() / word_size;

        for (size_t word = 0; word < word_cnt; ++word) {
                if (cpus->mask[word])
                        return false;
        }

        return true;
}

/** @}
 */

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub