bitops.h

/*
 * Copyright (c) 2020 jindongsheng1024@163.com
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef _BITOPS_H_
#define _BITOPS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

#define OP_BITS_PER_LONG 32
#define OP_BIT(nr)       (1UL << (nr))
#define OP_BIT_MASK(nr)  (1UL << ((nr) % OP_BITS_PER_LONG))
#define OP_BIT_WORD(nr)  ((nr) / OP_BITS_PER_LONG)

/*
 * Set a bit in memory
 */
static inline void set_bit(uint32_t *addr, uint32_t nr)
{
    uint32_t mask = OP_BIT_MASK(nr);
    uint32_t *p = ((uint32_t *)addr) + OP_BIT_WORD(nr);
    *p |= mask;
}

/*
 * Clear a bit in memory
 */
static inline void clear_bit(uint32_t *addr, uint32_t nr)
{
    uint32_t mask = OP_BIT_MASK(nr);
    uint32_t *p = ((uint32_t *)addr) + OP_BIT_WORD(nr);
    *p &= ~mask;
}

/*
 * Toggle a bit in memory
 */
static inline void change_bit(uint32_t *addr, uint32_t nr)
{
    uint32_t mask = OP_BIT_MASK(nr);
    uint32_t *p = ((uint32_t *)addr) + OP_BIT_WORD(nr);
    *p ^= mask;
}

/*
 * Set a bit and return its old value
 */
static inline int test_and_set_bit(uint32_t *addr, uint32_t nr)
{
    uint32_t mask = OP_BIT_MASK(nr);
    uint32_t *p = ((uint32_t *)addr) + OP_BIT_WORD(nr);
    uint32_t old = *p;
    *p = old | mask;
    return (old & mask) != 0;
}

/*
 * Clear a bit and return its old value
 */
static inline int test_and_clear_bit(uint32_t *addr, uint32_t nr)
{
    uint32_t mask = OP_BIT_MASK(nr);
    uint32_t *p = ((uint32_t *)addr) + OP_BIT_WORD(nr);
    uint32_t old = *p;
    *p = old & ~mask;
    return (old & mask) != 0;
}

/*
 * Toggle a bit and return its old value
 */
static inline int test_and_change_bit(uint32_t *addr, uint32_t nr)
{
    uint32_t mask = OP_BIT_MASK(nr);
    uint32_t *p = ((uint32_t *)addr) + OP_BIT_WORD(nr);
    uint32_t old = *p;
    *p = old ^ mask;
    return (old & mask) != 0;
}

/*
 * Determine whether a bit is set
 */
static inline int test_bit(uint32_t *addr, uint32_t nr)
{
    return 1UL & (addr[OP_BIT_WORD(nr)] >> (nr & (OP_BITS_PER_LONG-1)));
}

#ifdef __cplusplus
}
#endif

#endif

上一篇:awk流编辑器的使用


下一篇:[转]定制 Ubuntu 18.04 UEFI 启动盘初探(1)