summaryrefslogtreecommitdiff
path: root/lib/misc/util.h
blob: 35514eee01bb617a9a5afea43cc9efe93ae50516 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _LVM_UTIL_H
#define _LVM_UTIL_H

#include <inttypes.h>

#define min(a, b) ({ typeof(a) _a = (a); \
		     typeof(b) _b = (b); \
		     (void) (&_a == &_b); \
		     _a < _b ? _a : _b; })

#define max(a, b) ({ typeof(a) _a = (a); \
		     typeof(b) _b = (b); \
		     (void) (&_a == &_b); \
		     _a > _b ? _a : _b; })

#define is_power_of_2(n) ((n) && !((n) & ((n) - 1)))

#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6)
#define uninitialized_var(x) x
#else
#define uninitialized_var(x) x = x
#endif

/*
 * GCC 3.4 adds a __builtin_clz, which uses the count leading zeros (clz)
 * instruction on arches that have one. Provide a fallback using shifts
 * and comparisons for older compilers.
 */
#ifdef HAVE___BUILTIN_CLZ
#define clz(x) __builtin_clz((x))
#else /* ifdef HAVE___BUILTIN_CLZ */
static unsigned _dm_clz(unsigned x)
{
	int n;

	if ((int)x <= 0) return (~x >> 26) & 32;

	n = 1;

	if ((x >> 16) == 0) {
		n = n + 16;
		x = x << 16;
	}

	if ((x >> 24) == 0) {
		n = n + 8;
		x = x << 8;
	}

	if ((x >> 28) == 0) {
		n = n + 4;
		x = x << 4;
	}

	if ((x >> 30) == 0) {
		n = n + 2;
		x = x << 2;
	}
	n = n - (x >> 31);
	return n;
}
#define clz(x) _dm_clz((x))
#endif /* ifdef HAVE___BUILTIN_CLZ */

#ifdef HAVE___BUILTIN_CLZLL
#define clzll(x) __builtin_clzll((x))
#else /* ifdef HAVE___BUILTIN_CLZ */
static unsigned _dm_clzll(unsigned long long x)
{
	if (x <= 0xffffffff)
		return 32 + clz((unsigned) (x & 0xffffffff));

	return clz(x >> 32);
}
#define clzll(x) _dm_clzll((x))
#endif /* ifdef HAVE___BUILTIN_CLZLL */

#ifndef HAVE_FFS
#ifdef HAVE___BUILTIN_FFS
#define ffs(x) __builtin_ffs((x))
#else
#error ffs() not implemented!
#endif /* ifdef HAVE___BUILTIN_FFS */
#endif /* ifndef HAVE_FFS */

#define KERNEL_VERSION(major, minor, release) (((major) << 16) + ((minor) << 8) + (release))

/* Define some portable printing types */
#define PRIsize_t "zu"
#define PRIssize_t "zd"
#define PRIptrdiff_t "td"
#define PRIpid_t PRId32

/* For convenience */
#define FMTsize_t "%" PRIsize_t
#define FMTssize_t "%" PRIssize_t
#define FMTptrdiff_t "%" PRIptrdiff_t
#define FMTpid_t "%" PRIpid_t

#define FMTd8  "%" PRId8
#define FMTd16 "%" PRId16
#define FMTd32 "%" PRId32
#define FMTd64 "%" PRId64

#define FMTi8  "%" PRIi8
#define FMTi16 "%" PRIi16
#define FMTi32 "%" PRIi32
#define FMTi64 "%" PRIi64

#define FMTo8  "%" PRIo8
#define FMTo16 "%" PRIo16
#define FMTo32 "%" PRIo32
#define FMTo64 "%" PRIo64

#define FMTu8  "%" PRIu8
#define FMTu16 "%" PRIu16
#define FMTu32 "%" PRIu32
#define FMTu64 "%" PRIu64

#define FMTx8  "%" PRIx8
#define FMTx16 "%" PRIx16
#define FMTx32 "%" PRIx32
#define FMTx64 "%" PRIx64

#define FMTVGID "%." DM_TO_STRING(ID_LEN) "s"

#endif