Line | Branch | Exec | Source |
---|---|---|---|
1 | /*********************************************************************************/ | ||
2 | /* Copyright 2009-2024 Barcelona Supercomputing Center */ | ||
3 | /* */ | ||
4 | /* This file is part of the DLB library. */ | ||
5 | /* */ | ||
6 | /* DLB is free software: you can redistribute it and/or modify */ | ||
7 | /* it under the terms of the GNU Lesser General Public License as published by */ | ||
8 | /* the Free Software Foundation, either version 3 of the License, or */ | ||
9 | /* (at your option) any later version. */ | ||
10 | /* */ | ||
11 | /* DLB is distributed in the hope that it will be useful, */ | ||
12 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | ||
13 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | ||
14 | /* GNU Lesser General Public License for more details. */ | ||
15 | /* */ | ||
16 | /* You should have received a copy of the GNU Lesser General Public License */ | ||
17 | /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */ | ||
18 | /*********************************************************************************/ | ||
19 | |||
20 | /* Credits: https://nullprogram.com/blog/2016/10/07/ */ | ||
21 | |||
22 | #ifndef SMALL_ARRAY_H | ||
23 | #define SMALL_ARRAY_H | ||
24 | |||
25 | #ifdef HAVE_CONFIG_H | ||
26 | #include <config.h> | ||
27 | #endif | ||
28 | |||
29 | #include "support/queues.h" | ||
30 | |||
31 | #include <sys/types.h> | ||
32 | #include <stdlib.h> | ||
33 | |||
34 | #if NCPUS_AT_CONFIGURE_TIME > 1 && NCPUS_AT_CONFIGURE_TIME < 1025 | ||
35 | enum { SMALL_ARRAY_DEFAULT_SIZE = NCPUS_AT_CONFIGURE_TIME }; | ||
36 | #else | ||
37 | enum { SMALL_ARRAY_DEFAULT_SIZE = 64 }; | ||
38 | #endif | ||
39 | |||
40 | |||
41 | /*** SmallArray for int types ***/ | ||
42 | |||
43 | typedef struct SmallArrayInt { | ||
44 | size_t size; | ||
45 | int *values; | ||
46 | int buffer[SMALL_ARRAY_DEFAULT_SIZE]; | ||
47 | } small_array_int_t; | ||
48 | typedef small_array_int_t small_array_int; | ||
49 | |||
50 | static inline int* small_array_int_init(small_array_int_t *array, size_t size) { | ||
51 | array->size = size; | ||
52 | if (size <= SMALL_ARRAY_DEFAULT_SIZE) { | ||
53 | array->values = array->buffer; | ||
54 | } else { | ||
55 | array->values = malloc(sizeof(int) * size); | ||
56 | } | ||
57 | return array->values; | ||
58 | } | ||
59 | |||
60 | static inline void small_array_int_free(small_array_int_t *array) { | ||
61 | if (array->size > SMALL_ARRAY_DEFAULT_SIZE) { | ||
62 | free(array->values); | ||
63 | } | ||
64 | array->values = NULL; | ||
65 | } | ||
66 | |||
67 | |||
68 | /*** SmallArray for pid_t types ***/ | ||
69 | |||
70 | typedef struct SmallArrayPID { | ||
71 | size_t size; | ||
72 | pid_t *values; | ||
73 | pid_t buffer[SMALL_ARRAY_DEFAULT_SIZE]; | ||
74 | } small_array_pid_t; | ||
75 | |||
76 | static inline pid_t* small_array_pid_t_init(small_array_pid_t *array, size_t size) { | ||
77 | array->size = size; | ||
78 | if (size <= SMALL_ARRAY_DEFAULT_SIZE) { | ||
79 | array->values = array->buffer; | ||
80 | } else { | ||
81 | array->values = malloc(sizeof(pid_t) * size); | ||
82 | } | ||
83 | return array->values; | ||
84 | } | ||
85 | |||
86 | static inline void small_array_pid_t_free(small_array_pid_t *array) { | ||
87 | if (array->size > SMALL_ARRAY_DEFAULT_SIZE) { | ||
88 | free(array->values); | ||
89 | } | ||
90 | array->values = NULL; | ||
91 | } | ||
92 | |||
93 | |||
94 | /*** SmallArray for cpuid_t types ***/ | ||
95 | |||
96 | typedef struct SmallArrayCpuid { | ||
97 | size_t size; | ||
98 | cpuid_t *values; | ||
99 | cpuid_t buffer[SMALL_ARRAY_DEFAULT_SIZE]; | ||
100 | } small_array_cpuid_t; | ||
101 | |||
102 | 95 | static inline cpuid_t* small_array_cpuid_t_init(small_array_cpuid_t *array, size_t size) { | |
103 | 95 | array->size = size; | |
104 |
1/2✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
|
95 | if (size <= SMALL_ARRAY_DEFAULT_SIZE) { |
105 | 95 | array->values = array->buffer; | |
106 | } else { | ||
107 | ✗ | array->values = malloc(sizeof(cpuid_t) * size); | |
108 | } | ||
109 | 95 | return array->values; | |
110 | } | ||
111 | |||
112 | 95 | static inline void small_array_cpuid_t_free(small_array_cpuid_t *array) { | |
113 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
|
95 | if (array->size > SMALL_ARRAY_DEFAULT_SIZE) { |
114 | ✗ | free(array->values); | |
115 | } | ||
116 | 95 | array->values = NULL; | |
117 | 95 | } | |
118 | |||
119 | |||
120 | /*** SmallArray for lewi_request_t types ***/ | ||
121 | |||
122 | typedef struct SmallArrayLeWIRequest { | ||
123 | size_t size; | ||
124 | lewi_request_t *values; | ||
125 | lewi_request_t buffer[SMALL_ARRAY_DEFAULT_SIZE]; | ||
126 | } small_array_lewi_request_t; | ||
127 | |||
128 | 79 | static inline lewi_request_t* small_array_lewi_request_t_init( | |
129 | small_array_lewi_request_t *array, size_t size) { | ||
130 | 79 | array->size = size; | |
131 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 68 times.
|
79 | if (size <= SMALL_ARRAY_DEFAULT_SIZE) { |
132 | 11 | array->values = array->buffer; | |
133 | } else { | ||
134 | 68 | array->values = malloc(sizeof(lewi_request_t) * size); | |
135 | } | ||
136 | 79 | return array->values; | |
137 | } | ||
138 | |||
139 | 79 | static inline void small_array_lewi_request_t_free(small_array_lewi_request_t *array) { | |
140 |
2/2✓ Branch 0 taken 68 times.
✓ Branch 1 taken 11 times.
|
79 | if (array->size > SMALL_ARRAY_DEFAULT_SIZE) { |
141 | 68 | free(array->values); | |
142 | } | ||
143 | 79 | array->values = NULL; | |
144 | 79 | } | |
145 | |||
146 | #define SMALL_ARRAY(type, var_name, size) \ | ||
147 | small_array_##type __##var_name __attribute__ ((__cleanup__(small_array_##type##_free))); \ | ||
148 | type *var_name = small_array_##type##_init(&__##var_name, size); | ||
149 | |||
150 | |||
151 | #endif /* SMALL_ARRAY_H */ | ||
152 |