Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / libcfs / include / libcfs / user-bitops.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2004 Cluster File Systems, Inc.
5  * Author: Nikita Danilov <nikita@clusterfs.com>
6  *
7  * This file is part of Lustre, http://www.lustre.org.
8  *
9  * Lustre is free software; you can redistribute it and/or modify it under the
10  * terms of version 2 of the GNU General Public License as published by the
11  * Free Software Foundation.
12  *
13  * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
20  * Ave, Cambridge, MA 02139, USA.
21  *
22  * Implementation of portable time API for user-level.
23  *
24  */
25
26 #ifndef __LIBCFS_USER_BITOPS_H__
27 #define __LIBCFS_USER_BITOPS_H__
28
29 /* test if bit nr is set in bitmap addr; returns previous value of bit nr */
30 static __inline__ int set_bit(int nr, unsigned long * addr)
31 {
32         long    mask;
33
34         addr += nr / BITS_PER_LONG;
35         mask = 1UL << (nr & (BITS_PER_LONG - 1));
36         nr = (mask & *addr) != 0;
37         *addr |= mask;
38         return nr;
39 }
40
41 /* clear bit nr in bitmap addr; returns previous value of bit nr*/
42 static __inline__ int clear_bit(int nr, unsigned long * addr)
43 {
44         long    mask;
45
46         addr += nr / BITS_PER_LONG;
47         mask = 1UL << (nr & (BITS_PER_LONG - 1));
48         nr = (mask & *addr) != 0;
49         *addr &= ~mask;
50         return nr;
51 }
52
53 static __inline__ int test_bit(int nr, const unsigned long * addr)
54 {
55         return ((1UL << (nr & (BITS_PER_LONG - 1))) & ((addr)[nr / BITS_PER_LONG])) != 0;
56 }
57
58 /* using binary seach */
59 static __inline__ unsigned long __ffs(long data)
60 {
61         int pos = 0;
62
63 #if BITS_PER_LONG == 64
64         if ((data & 0xFFFFFFFF) == 0) {
65                 pos += 32;
66                 data >>= 32;
67         }
68 #endif
69         if ((data & 0xFFFF) == 0) {
70                 pos += 16;
71                 data >>= 16;
72         }
73         if ((data & 0xFF) == 0) {
74                 pos += 8;
75                 data >>= 8;
76         }
77         if ((data & 0xF) == 0) {
78                 pos += 4;
79                 data >>= 4;
80         }
81         if ((data & 0x3) == 0) {
82                 pos += 2;
83                 data >>= 2;
84         }
85         if ((data & 0x1) == 0)
86                 pos += 1;
87
88         return pos;
89 }
90
91 #define __ffz(x)        __ffs(~(x))
92
93 unsigned long find_next_bit(unsigned long *addr,
94                             unsigned long size, unsigned long offset);
95
96 unsigned long find_next_zero_bit(unsigned long *addr,
97                                  unsigned long size, unsigned long offset);
98
99 #define find_first_bit(addr,size)       (find_next_bit((addr),(size),0))
100 #define find_first_zero_bit(addr,size)  (find_next_zero_bit((addr),(size),0))
101
102 #endif