Whamcloud - gitweb
Fixes some scability and access to not inited memory problems
[fs/lustre-release.git] / lnet / libcfs / user-bitops.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2007 Cluster File Systems, Inc.
5  *
6  * This file is part of Lustre, http://www.lustre.org.
7  *
8  * Lustre is free software; you can redistribute it and/or modify it under the
9  * terms of version 2 of the GNU General Public License as published by the
10  * Free Software Foundation.
11  *
12  * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
19  * Ave, Cambridge, MA 02139, USA.
20  *
21  */
22 #ifndef __KERNEL__
23
24 #include <libcfs/libcfs.h>
25 #include <libcfs/kp30.h>
26
27 #include <string.h> /* for ffs - confirm POSIX */
28
29 #define BITS_PER_WORD           32
30 #define OFF_BY_START(start)     ((start)/BITS_PER_WORD)
31
32 unsigned long find_next_bit(const unsigned int *addr,
33                 unsigned long size, unsigned long offset)
34 {
35         uint32_t *word, *last;
36         unsigned int first_bit, bit, base;
37
38         word = addr + OFF_BY_START(offset);
39         last = addr + OFF_BY_START(size-1);
40         first_bit = offset % BITS_PER_WORD;
41         base = offset - first_bit;
42
43         if (offset >= size)
44                 return size;
45         if (first_bit != 0) {
46                 int tmp = (*word++) & (~0UL << first_bit);
47                 bit = ffs(tmp);
48                 if (bit < BITS_PER_WORD)
49                         goto found;
50                 word++;
51                 base += BITS_PER_WORD;
52         }
53         while (word <= last) {
54                 if (*word != 0ul) {
55                         bit = ffs(*word);
56                         goto found;
57                 }
58                 word++;
59                 base += BITS_PER_WORD;
60         }
61         return size;
62 found:
63         return base + bit;
64 }
65
66 unsigned long find_next_zero_bit(const unsigned int *addr,
67                 unsigned long size, unsigned long offset)
68 {
69         uint32_t *word, *last;
70         unsigned int first_bit, bit, base;
71
72         word = addr + OFF_BY_START(offset);
73         last = addr + OFF_BY_START(size-1);
74         first_bit = offset % BITS_PER_WORD;
75         base = offset - first_bit;
76
77         if (offset >= size)
78                 return size;
79         if (first_bit != 0) {
80                 int tmp = (*word++) & (~0UL << first_bit);
81                 bit = ffs(~tmp);
82                 if (bit < BITS_PER_WORD)
83                         goto found;
84                 word++;
85                 base += BITS_PER_WORD;
86         }
87         while (word <= last) {
88                 if (*word != ~0ul) {
89                         bit = ffs(*word);
90                         goto found;
91                 }
92                 word++;
93                 base += BITS_PER_WORD;
94         }
95         return size;
96 found:
97         return base + bit;
98 }
99
100 #endif