radv: set writes_memory for global memory stores/atomics
[mesa.git] / src / gallium / auxiliary / util / u_bitmask.c
index 23c93a3ebcb987c86a11e490b542ef9634253e86..433a09dd0d230629df140db0f8fe75cd3b49b7ac 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
+ *
  * Copyright 2009 VMware, Inc.
  * All Rights Reserved.
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  **************************************************************************/
 
 /**
  * @file
  * Generic bitmask implementation.
- *  
+ *
  * @author Jose Fonseca <jfonseca@vmware.com>
  */
 
@@ -40,7 +40,7 @@
 #include "util/u_bitmask.h"
 
 
-typedef uint32_t util_bitmask_word;  
+typedef uint32_t util_bitmask_word;
 
 
 #define UTIL_BITMASK_INITIAL_WORDS 16
@@ -51,10 +51,10 @@ typedef uint32_t util_bitmask_word;
 struct util_bitmask
 {
    util_bitmask_word *words;
-   
+
    /** Number of bits we can currently hold */
    unsigned size;
-   
+
    /** Number of consecutive bits set at the start of the bitmask */
    unsigned filled;
 };
@@ -64,94 +64,100 @@ struct util_bitmask *
 util_bitmask_create(void)
 {
    struct util_bitmask *bm;
-   
+
    bm = MALLOC_STRUCT(util_bitmask);
-   if(!bm)
+   if (!bm)
       return NULL;
-   
-   bm->words = (util_bitmask_word *)CALLOC(UTIL_BITMASK_INITIAL_WORDS, sizeof(util_bitmask_word));
-   if(!bm->words) {
+
+   bm->words = (util_bitmask_word *)
+      CALLOC(UTIL_BITMASK_INITIAL_WORDS, sizeof(util_bitmask_word));
+   if (!bm->words) {
       FREE(bm);
       return NULL;
    }
-   
+
    bm->size = UTIL_BITMASK_INITIAL_WORDS * UTIL_BITMASK_BITS_PER_WORD;
    bm->filled = 0;
-   
+
    return bm;
 }
 
 
 /**
- * Resize the bitmask if necessary 
+ * Resize the bitmask if necessary
  */
-static INLINE boolean
+static inline boolean
 util_bitmask_resize(struct util_bitmask *bm,
                     unsigned minimum_index)
 {
-   unsigned minimum_size = minimum_index + 1;
+   const unsigned minimum_size = minimum_index + 1;
    unsigned new_size;
    util_bitmask_word *new_words;
 
    /* Check integer overflow */
-   if(!minimum_size)
+   if (!minimum_size)
       return FALSE;
-      
-   if(bm->size >= minimum_size)
+
+   if (bm->size >= minimum_size)
       return TRUE;
 
    assert(bm->size % UTIL_BITMASK_BITS_PER_WORD == 0);
    new_size = bm->size;
-   while(new_size < minimum_size) {
+   while (new_size < minimum_size) {
       new_size *= 2;
       /* Check integer overflow */
-      if(new_size < bm->size)
+      if (new_size < bm->size)
          return FALSE;
    }
    assert(new_size);
    assert(new_size % UTIL_BITMASK_BITS_PER_WORD == 0);
-   
-   new_words = (util_bitmask_word *)REALLOC((void *)bm->words,
-                                            bm->size / UTIL_BITMASK_BITS_PER_BYTE,
-                                            new_size / UTIL_BITMASK_BITS_PER_BYTE);
-   if(!new_words)
+
+   new_words = (util_bitmask_word *)
+      REALLOC((void *)bm->words,
+              bm->size / UTIL_BITMASK_BITS_PER_BYTE,
+              new_size / UTIL_BITMASK_BITS_PER_BYTE);
+   if (!new_words)
       return FALSE;
-   
-   memset(new_words + bm->size/UTIL_BITMASK_BITS_PER_WORD, 
-          0, 
+
+   memset(new_words + bm->size/UTIL_BITMASK_BITS_PER_WORD,
+          0,
           (new_size - bm->size)/UTIL_BITMASK_BITS_PER_BYTE);
-   
+
    bm->size = new_size;
    bm->words = new_words;
-   
+
    return TRUE;
 }
 
 
 /**
- * Lazily update the filled.
+ * Check if we can increment the filled counter.
  */
-static INLINE void
+static inline void
 util_bitmask_filled_set(struct util_bitmask *bm,
                         unsigned index)
 {
    assert(bm->filled <= bm->size);
    assert(index < bm->size);
-   
-   if(index == bm->filled) {
+
+   if (index == bm->filled) {
       ++bm->filled;
       assert(bm->filled <= bm->size);
    }
 }
 
-static INLINE void
+
+/**
+ * Check if we need to decrement the filled counter.
+ */
+static inline void
 util_bitmask_filled_unset(struct util_bitmask *bm,
                           unsigned index)
 {
    assert(bm->filled <= bm->size);
    assert(index < bm->size);
-   
-   if(index < bm->filled)
+
+   if (index < bm->filled)
       bm->filled = index;
 }
 
@@ -162,16 +168,16 @@ util_bitmask_add(struct util_bitmask *bm)
    unsigned word;
    unsigned bit;
    util_bitmask_word mask;
-   
+
    assert(bm);
 
-   /* linear search for an empty index */
+   /* linear search for an empty index, starting at filled position */
    word = bm->filled / UTIL_BITMASK_BITS_PER_WORD;
    bit  = bm->filled % UTIL_BITMASK_BITS_PER_WORD;
    mask = 1 << bit;
-   while(word < bm->size / UTIL_BITMASK_BITS_PER_WORD) {
-      while(bit < UTIL_BITMASK_BITS_PER_WORD) {
-         if(!(bm->words[word] & mask))
+   while (word < bm->size / UTIL_BITMASK_BITS_PER_WORD) {
+      while (bit < UTIL_BITMASK_BITS_PER_WORD) {
+         if (!(bm->words[word] & mask))
             goto found;
          ++bm->filled;
          ++bit;
@@ -184,7 +190,7 @@ util_bitmask_add(struct util_bitmask *bm)
 found:
 
    /* grow the bitmask if necessary */
-   if(!util_bitmask_resize(bm, bm->filled))
+   if (!util_bitmask_resize(bm, bm->filled))
       return UTIL_BITMASK_INVALID_INDEX;
 
    assert(!(bm->words[word] & mask));
@@ -195,17 +201,17 @@ found:
 
 
 unsigned
-util_bitmask_set(struct util_bitmask *bm, 
+util_bitmask_set(struct util_bitmask *bm,
                  unsigned index)
 {
    unsigned word;
    unsigned bit;
    util_bitmask_word mask;
-   
+
    assert(bm);
-   
+
    /* grow the bitmask if necessary */
-   if(!util_bitmask_resize(bm, index))
+   if (!util_bitmask_resize(bm, index))
       return UTIL_BITMASK_INVALID_INDEX;
 
    word = index / UTIL_BITMASK_BITS_PER_WORD;
@@ -215,22 +221,22 @@ util_bitmask_set(struct util_bitmask *bm,
    bm->words[word] |= mask;
 
    util_bitmask_filled_set(bm, index);
-   
+
    return index;
 }
 
 
 void
-util_bitmask_clear(struct util_bitmask *bm, 
+util_bitmask_clear(struct util_bitmask *bm,
                    unsigned index)
 {
    unsigned word;
    unsigned bit;
    util_bitmask_word mask;
-   
+
    assert(bm);
-   
-   if(index >= bm->size)
+
+   if (index >= bm->size)
       return;
 
    word = index / UTIL_BITMASK_BITS_PER_WORD;
@@ -238,30 +244,30 @@ util_bitmask_clear(struct util_bitmask *bm,
    mask = 1 << bit;
 
    bm->words[word] &= ~mask;
-   
+
    util_bitmask_filled_unset(bm, index);
 }
 
 
 boolean
-util_bitmask_get(struct util_bitmask *bm, 
+util_bitmask_get(struct util_bitmask *bm,
                  unsigned index)
 {
-   unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
-   unsigned bit  = index % UTIL_BITMASK_BITS_PER_WORD;
-   util_bitmask_word mask = 1 << bit;
-   
+   const unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
+   const unsigned bit  = index % UTIL_BITMASK_BITS_PER_WORD;
+   const util_bitmask_word mask = 1 << bit;
+
    assert(bm);
-   
-   if(index < bm->filled) {
+
+   if (index < bm->filled) {
       assert(bm->words[word] & mask);
       return TRUE;
    }
 
-   if(index >= bm->size)
+   if (index >= bm->size)
       return FALSE;
 
-   if(bm->words[word] & mask) {
+   if (bm->words[word] & mask) {
       util_bitmask_filled_set(bm, index);
       return TRUE;
    }
@@ -271,27 +277,27 @@ util_bitmask_get(struct util_bitmask *bm,
 
 
 unsigned
-util_bitmask_get_next_index(struct util_bitmask *bm, 
+util_bitmask_get_next_index(struct util_bitmask *bm,
                             unsigned index)
 {
    unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
    unsigned bit  = index % UTIL_BITMASK_BITS_PER_WORD;
    util_bitmask_word mask = 1 << bit;
 
-   if(index < bm->filled) {
+   if (index < bm->filled) {
       assert(bm->words[word] & mask);
       return index;
    }
 
-   if(index >= bm->size) {
+   if (index >= bm->size) {
       return UTIL_BITMASK_INVALID_INDEX;
    }
 
    /* Do a linear search */
-   while(word < bm->size / UTIL_BITMASK_BITS_PER_WORD) {
-      while(bit < UTIL_BITMASK_BITS_PER_WORD) {
-         if(bm->words[word] & mask) {
-            if(index == bm->filled) {
+   while (word < bm->size / UTIL_BITMASK_BITS_PER_WORD) {
+      while (bit < UTIL_BITMASK_BITS_PER_WORD) {
+         if (bm->words[word] & mask) {
+            if (index == bm->filled) {
                ++bm->filled;
                assert(bm->filled <= bm->size);
             }
@@ -305,7 +311,7 @@ util_bitmask_get_next_index(struct util_bitmask *bm,
       bit = 0;
       mask = 1;
    }
-   
+
    return UTIL_BITMASK_INVALID_INDEX;
 }
 
@@ -320,9 +326,8 @@ util_bitmask_get_first_index(struct util_bitmask *bm)
 void
 util_bitmask_destroy(struct util_bitmask *bm)
 {
-   assert(bm);
-
-   FREE(bm->words);
-   FREE(bm);
+   if (bm) {
+      FREE(bm->words);
+      FREE(bm);
+   }
 }
-