[threads] Remove mono_threads_create_thread (#4411)
[mono.git] / mono / utils / monobitset.c
index 48ceb714bd44e42bef208082fcc8a633e69c43b9..2f6b6c501037c6cd070612896455c227b3f2b9ae 100644 (file)
@@ -4,23 +4,11 @@
 #include "monobitset.h"
 #include "config.h"
 
-#ifdef __GNUC__
-#define MONO_ZERO_LEN_ARRAY 0
-#else
-#define MONO_ZERO_LEN_ARRAY 1
-#endif
-
 #define BITS_PER_CHUNK MONO_BITSET_BITS_PER_CHUNK
 
-struct MonoBitSet {
-       gsize size;
-       gsize flags;
-       gsize data [MONO_ZERO_LEN_ARRAY];
-};
-
 /*
  * mono_bitset_alloc_size:
- * @max_size: The numer of bits you want to hold
+ * @max_size: The number of bits you want to hold
  * @flags: unused
  *
  * Return the number of bytes required to hold the bitset.
@@ -47,7 +35,7 @@ mono_bitset_new (guint32 max_size, guint32 flags) {
        guint32 real_size = (max_size + BITS_PER_CHUNK - 1) / BITS_PER_CHUNK;
        MonoBitSet *result;
 
-       result = g_malloc0 (sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY));
+       result = (MonoBitSet *) g_malloc0 (sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY));
        result->size = real_size * BITS_PER_CHUNK;
        result->flags = flags;
        return result;
@@ -66,7 +54,7 @@ mono_bitset_new (guint32 max_size, guint32 flags) {
 MonoBitSet *
 mono_bitset_mem_new (gpointer mem, guint32 max_size, guint32 flags) {
        guint32 real_size = (max_size + BITS_PER_CHUNK - 1) / BITS_PER_CHUNK;
-       MonoBitSet *result = mem;
+       MonoBitSet *result = (MonoBitSet *) mem;
 
        result->size = real_size * BITS_PER_CHUNK;
        result->flags = flags | MONO_BITSET_DONT_FREE;
@@ -222,25 +210,17 @@ mono_bitset_count (const MonoBitSet *set) {
        count = 0;
        for (i = 0; i < set->size / BITS_PER_CHUNK; ++i) {
                d = set->data [i];
-               /* there is probably some asm code that can do this much faster */
-               if (d) {
-#if SIZEOF_VOID_P == 8
-                       /* http://www.jjj.de/bitwizardry/bitwizardrypage.html */
-                       d -=  (d>>1) & 0x5555555555555555;
-                       d  = ((d>>2) & 0x3333333333333333) + (d & 0x3333333333333333);
-                       d  = ((d>>4) + d) & 0x0f0f0f0f0f0f0f0f;
-                       d *= 0x0101010101010101;
-                       count += d >> 56;
+#ifdef __GNUC__
+               if (sizeof (gsize) == sizeof (unsigned int))
+                       count += __builtin_popcount (d);
+               else
+                       count += __builtin_popcountll (d);
 #else
-                       /* http://aggregate.org/MAGIC/ */
-                       d -= ((d >> 1) & 0x55555555);
-                       d = (((d >> 2) & 0x33333333) + (d & 0x33333333));
-                       d = (((d >> 4) + d) & 0x0f0f0f0f);
-                       d += (d >> 8);
-                       d += (d >> 16);
-                       count += (d & 0x0000003f);
-#endif
+               while (d) {
+                       count ++;
+                       d &= (d - 1);
                }
+#endif
        }
        return count;
 }
@@ -297,7 +277,11 @@ my_g_bit_nth_lsf (gsize mask, gint nth_bit)
        if ((mask == 0) || (nth_bit == BITS_PER_CHUNK))
                return -1;
 
-#if defined(__i386__) && defined(__GNUC__)
+#if defined(__native_client__) && (defined(__i386__) || defined(__x86_64))
+#define USE_X86_32BIT_INSTRUCTIONS 1
+#endif
+
+#if (defined(__i386__) && defined(__GNUC__)) || defined(USE_X86_32BIT_INSTRUCTIONS)
  {
         int r;
         /* This depends on mask != 0 */
@@ -327,7 +311,7 @@ static inline gint
 my_g_bit_nth_lsf_nomask (gsize mask)
 {
        /* Mask is expected to be != 0 */
-#if defined(__i386__) && defined(__GNUC__)
+#if (defined(__i386__) && defined(__GNUC__)) || defined(USE_X86_32BIT_INSTRUCTIONS)
        int r;
 
        __asm__("bsfl %1,%0\n\t"
@@ -384,7 +368,7 @@ my_g_bit_nth_msf (gsize mask,
 }
 
 static int
-find_first_unset (gulong mask, gint nth_bit)
+find_first_unset (gsize mask, gint nth_bit)
 {
        do {
                nth_bit++;
@@ -566,11 +550,12 @@ mono_bitset_copyto (const MonoBitSet *src, MonoBitSet *dest) {
  */
 void
 mono_bitset_union (MonoBitSet *dest, const MonoBitSet *src) {
-       int i;
+       int i, size;
 
        g_assert (src->size <= dest->size);
 
-       for (i = 0; i < dest->size / BITS_PER_CHUNK; ++i)
+       size = dest->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
                dest->data [i] |= src->data [i];
 }
 
@@ -583,12 +568,13 @@ mono_bitset_union (MonoBitSet *dest, const MonoBitSet *src) {
  */
 void
 mono_bitset_intersection (MonoBitSet *dest, const MonoBitSet *src) {
-       int i;
+       int i, size;
 
        g_assert (src->size <= dest->size);
 
-       for (i = 0; i < dest->size / BITS_PER_CHUNK; ++i)
-               dest->data [i] = dest->data [i] & src->data [i];
+       size = dest->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
+               dest->data [i] &= src->data [i];
 }
 
 /*
@@ -601,12 +587,13 @@ mono_bitset_intersection (MonoBitSet *dest, const MonoBitSet *src) {
  */
 void
 mono_bitset_intersection_2 (MonoBitSet *dest, const MonoBitSet *src1, const MonoBitSet *src2) {
-       int i;
+       int i, size;
 
        g_assert (src1->size <= dest->size);
        g_assert (src2->size <= dest->size);
 
-       for (i = 0; i < dest->size / BITS_PER_CHUNK; ++i)
+       size = dest->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
                dest->data [i] = src1->data [i] & src2->data [i];
 }
 
@@ -619,11 +606,12 @@ mono_bitset_intersection_2 (MonoBitSet *dest, const MonoBitSet *src1, const Mono
  */
 void
 mono_bitset_sub (MonoBitSet *dest, const MonoBitSet *src) {
-       int i;
+       int i, size;
 
        g_assert (src->size <= dest->size);
 
-       for (i = 0; i < src->size / BITS_PER_CHUNK; ++i)
+       size = src->size / BITS_PER_CHUNK;
+       for (i = 0; i < size; ++i)
                dest->data [i] &= ~src->data [i];
 }
 
@@ -825,4 +813,3 @@ main() {
 }
 
 #endif
-