[sgen] Fix race conditions in worker thread start/stop.
[mono.git] / mono / metadata / mono-ptr-array.h
index ecc0e42696cb053a28ced1cabc0a3f9aaecafd21..a828f4e9f4db396d02d12dde27384493aae46a81 100644 (file)
@@ -17,6 +17,7 @@
 
 /* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
  * It works by allocating an initial small array on stack and only going to gc tracked memory if needed.
+ * The array elements are assumed to be object references.
  */
 typedef struct {
        void **data;
@@ -29,7 +30,7 @@ typedef struct {
 #define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
        (ARRAY).size = 0; \
        (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
-       (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
+       (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, mono_gc_make_root_descr_all_refs (INITIAL_SIZE)) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
 } while (0)
 
 #define mono_ptr_array_destroy(ARRAY) do {\
@@ -39,8 +40,8 @@ typedef struct {
 
 #define mono_ptr_array_append(ARRAY, VALUE) do { \
        if ((ARRAY).size >= (ARRAY).capacity) {\
-               void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
-               memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
+       void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, mono_gc_make_root_descr_all_refs ((ARRAY).capacity * 2)); \
+               mono_gc_memmove (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
                if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK)     \
                        mono_gc_free_fixed ((ARRAY).data);      \
                (ARRAY).data = __tmp;   \
@@ -61,4 +62,13 @@ typedef struct {
 
 #define mono_ptr_array_size(ARRAY) ((ARRAY).size)
 
+#define mono_ptr_array_reset(ARRAY) do { \
+       (ARRAY).size = 0; \
+} while (0)
+
+#define mono_ptr_array_clear(ARRAY) do { \
+       (ARRAY).size = 0; \
+       mono_gc_bzero ((ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
+} while (0)
+
 #endif