Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cnt32_to_63.h
Go to the documentation of this file.
1 /*
2  * Extend a 32-bit counter to 63 bits
3  *
4  * Author: Nicolas Pitre
5  * Created: December 3, 2006
6  * Copyright: MontaVista Software, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2
10  * as published by the Free Software Foundation.
11  */
12 
13 #ifndef __LINUX_CNT32_TO_63_H__
14 #define __LINUX_CNT32_TO_63_H__
15 
16 #include <linux/compiler.h>
17 #include <linux/types.h>
18 #include <asm/byteorder.h>
19 
20 /* this is used only to give gcc a clue about good code generation */
21 union cnt32_to_63 {
22  struct {
23 #if defined(__LITTLE_ENDIAN)
24  u32 lo, hi;
25 #elif defined(__BIG_ENDIAN)
26  u32 hi, lo;
27 #endif
28  };
30 };
31 
32 
95 #define cnt32_to_63(cnt_lo) \
96 ({ \
97  static u32 __m_cnt_hi; \
98  union cnt32_to_63 __x; \
99  __x.hi = __m_cnt_hi; \
100  smp_rmb(); \
101  __x.lo = (cnt_lo); \
102  if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \
103  __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \
104  __x.val; \
105 })
106 
107 #endif