[System] Fixes UdpClient.Receive with IPv6 endpoint
[mono.git] / mono / metadata / mono-ptr-array.h
1 /*
2  * mono-ptr-array.h: GC aware equivalente of g_ptr_array
3  *
4  * Author:
5  *      Rodrigo Kumpera  <rkumpera@novell.com>
6  *
7  * (C) 2010 Novell, Inc
8  */
9
10 #ifndef __MONO_PTR_ARRAY_H__
11 #define __MONO_PTR_ARRAY_H__
12
13
14 #include <glib.h>
15
16 #include "mono/metadata/gc-internal.h"
17
18 /* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
19  * It works by allocating an initial small array on stack and only going to gc tracked memory if needed.
20  * The array elements are assumed to be object references.
21  */
22 typedef struct {
23         void **data;
24         int size;
25         int capacity;
26         MonoGCRootSource source;
27         const char *msg;
28 } MonoPtrArray;
29
30 #define MONO_PTR_ARRAY_MAX_ON_STACK (16)
31
32 #define mono_ptr_array_init(ARRAY, INITIAL_SIZE, SOURCE, MSG) do {\
33         (ARRAY).size = 0; \
34         (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
35         (ARRAY).source = SOURCE; \
36         (ARRAY).msg = MSG; \
37         (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), SOURCE, MSG) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
38 } while (0)
39
40 #define mono_ptr_array_destroy(ARRAY) do {\
41         if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
42                 mono_gc_free_fixed ((ARRAY).data); \
43 } while (0)
44
45 #define mono_ptr_array_append(ARRAY, VALUE) do { \
46         if ((ARRAY).size >= (ARRAY).capacity) {\
47         void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, mono_gc_make_root_descr_all_refs ((ARRAY).capacity * 2), (ARRAY).source, (ARRAY).msg); \
48                 mono_gc_memmove_aligned (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
49                 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK)     \
50                         mono_gc_free_fixed ((ARRAY).data);      \
51                 (ARRAY).data = __tmp;   \
52                 (ARRAY).capacity *= 2;\
53         }\
54         ((ARRAY).data [(ARRAY).size++] = VALUE); \
55 } while (0)
56
57 #define mono_ptr_array_sort(ARRAY, COMPARE_FUNC) do { \
58         qsort ((ARRAY).data, (ARRAY).size, sizeof (gpointer), (COMPARE_FUNC)); \
59 } while (0)
60
61 #define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
62         ((ARRAY).data [(IDX)] = VALUE); \
63 } while (0)
64
65 #define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
66
67 #define mono_ptr_array_size(ARRAY) ((ARRAY).size)
68
69 #define mono_ptr_array_reset(ARRAY) do { \
70         (ARRAY).size = 0; \
71 } while (0)
72
73 #define mono_ptr_array_clear(ARRAY) do { \
74         (ARRAY).size = 0; \
75         mono_gc_bzero_aligned ((ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
76 } while (0)
77
78 #endif