原子变量

要点

  • 对于内核来说,单核和多核是不同的,涉及到同一时刻有几个内核实例在运行。而对于进程,即使只有单核心,也存在并发问题。
  • 对于单核心的内核来说,是否要加LOCK前缀,个人感觉某些情况也是要加的。(虽然代码中将单核心LOCK前缀定义为空)

LOCK

code

include/linux/types.h

typedef struct {
    int counter;
} atomic_t;

#ifdef CONFIG_64BIT
typedef struct {
    s64 counter;
} atomic64_t;
#endif
include/linux/atomic/atomic-instrumented.h

static inline void
atomic_add(int i, atomic_t *v)
{
    kasan_check_write(v, sizeof(*v));
    arch_atomic_add(i, v);
}
#define atomic_add atomic_add

static __always_inline void
atomic64_add(s64 i, atomic64_t *v)
{
    instrument_atomic_read_write(v, sizeof(*v));
    arch_atomic64_add(i, v);
}
arch/x86/include/asm/atomic.h

/**
 * arch_atomic_add - add integer to atomic variable
 * @i: integer value to add
 * @v: pointer of type atomic_t
 *
 * Atomically adds @i to @v.
 */
static __always_inline void arch_atomic_add(int i, atomic_t *v)
{
    asm volatile(LOCK_PREFIX "addl %1,%0"
             : "+m" (v->counter)
             : "ir" (i) : "memory");
}
./arch/x86/include/asm/atomic64_64.h

/**
 * arch_atomic64_add - add integer to atomic64 variable
 * @i: integer value to add
 * @v: pointer to type atomic64_t
 *
 * Atomically adds @i to @v.
 */
static __always_inline void arch_atomic64_add(s64 i, atomic64_t *v)
{
    asm volatile(LOCK_PREFIX "addq %1,%0"
             : "=m" (v->counter)
             : "er" (i), "m" (v->counter) : "memory");
}
./arch/x86/include/asm/alternative.h

#ifdef CONFIG_SMP
#define LOCK_PREFIX_HERE \
        ".pushsection .smp_locks,\"a\"\n"    \
        ".balign 4\n"                \
        ".long 671f - .\n" /* offset */        \
        ".popsection\n"                \
        "671:"

#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; "

#else /* ! CONFIG_SMP */
#define LOCK_PREFIX_HERE ""
#define LOCK_PREFIX ""
#endif

results matching ""

    No results matching ""