Path: blob/master/include/asm-generic/cmpxchg-local.h
10817 views
#ifndef __ASM_GENERIC_CMPXCHG_LOCAL_H1#define __ASM_GENERIC_CMPXCHG_LOCAL_H23#include <linux/types.h>4#include <linux/irqflags.h>56extern unsigned long wrong_size_cmpxchg(volatile void *ptr);78/*9* Generic version of __cmpxchg_local (disables interrupts). Takes an unsigned10* long parameter, supporting various types of architectures.11*/12static inline unsigned long __cmpxchg_local_generic(volatile void *ptr,13unsigned long old, unsigned long new, int size)14{15unsigned long flags, prev;1617/*18* Sanity checking, compile-time.19*/20if (size == 8 && sizeof(unsigned long) != 8)21wrong_size_cmpxchg(ptr);2223local_irq_save(flags);24switch (size) {25case 1: prev = *(u8 *)ptr;26if (prev == old)27*(u8 *)ptr = (u8)new;28break;29case 2: prev = *(u16 *)ptr;30if (prev == old)31*(u16 *)ptr = (u16)new;32break;33case 4: prev = *(u32 *)ptr;34if (prev == old)35*(u32 *)ptr = (u32)new;36break;37case 8: prev = *(u64 *)ptr;38if (prev == old)39*(u64 *)ptr = (u64)new;40break;41default:42wrong_size_cmpxchg(ptr);43}44local_irq_restore(flags);45return prev;46}4748/*49* Generic version of __cmpxchg64_local. Takes an u64 parameter.50*/51static inline u64 __cmpxchg64_local_generic(volatile void *ptr,52u64 old, u64 new)53{54u64 prev;55unsigned long flags;5657local_irq_save(flags);58prev = *(u64 *)ptr;59if (prev == old)60*(u64 *)ptr = new;61local_irq_restore(flags);62return prev;63}6465#endif666768