@@ -62,15 +62,31 @@ struct bench_params {
6262 unsigned int nr_loops ;
6363};
6464
65+ struct bench_mem_info {
66+ const struct function * functions ;
67+ int (* do_op )(const struct function * r , struct bench_params * p ,
68+ void * src , void * dst , union bench_clock * rt );
69+ const char * const * usage ;
70+ bool alloc_src ;
71+ };
72+
73+ typedef bool (* mem_init_t )(struct bench_mem_info * , struct bench_params * ,
74+ void * * , void * * );
75+ typedef void (* mem_fini_t )(struct bench_mem_info * , struct bench_params * ,
76+ void * * , void * * );
6577typedef void * (* memcpy_t )(void * , const void * , size_t );
6678typedef void * (* memset_t )(void * , int , size_t );
6779
6880struct function {
6981 const char * name ;
7082 const char * desc ;
71- union {
72- memcpy_t memcpy ;
73- memset_t memset ;
83+ struct {
84+ mem_init_t init ;
85+ mem_fini_t fini ;
86+ union {
87+ memcpy_t memcpy ;
88+ memset_t memset ;
89+ };
7490 } fn ;
7591};
7692
@@ -138,37 +154,24 @@ static double timeval2double(struct timeval *ts)
138154 printf(" %14lf GB/sec\n", x / K / K / K); \
139155 } while (0)
140156
141- struct bench_mem_info {
142- const struct function * functions ;
143- union bench_clock (* do_op )(const struct function * r , struct bench_params * p ,
144- void * src , void * dst );
145- const char * const * usage ;
146- bool alloc_src ;
147- };
148-
149157static void __bench_mem_function (struct bench_mem_info * info , struct bench_params * p ,
150158 int r_idx )
151159{
152160 const struct function * r = & info -> functions [r_idx ];
153161 double result_bps = 0.0 ;
154162 union bench_clock rt = { 0 };
155- void * src = NULL , * dst = zalloc ( p -> size ) ;
163+ void * src = NULL , * dst = NULL ;
156164
157165 printf ("# function '%s' (%s)\n" , r -> name , r -> desc );
158166
159- if (dst == NULL )
160- goto out_alloc_failed ;
161-
162- if (info -> alloc_src ) {
163- src = zalloc (p -> size );
164- if (src == NULL )
165- goto out_alloc_failed ;
166- }
167+ if (r -> fn .init && r -> fn .init (info , p , & src , & dst ))
168+ goto out_init_failed ;
167169
168170 if (bench_format == BENCH_FORMAT_DEFAULT )
169171 printf ("# Copying %s bytes ...\n\n" , size_str );
170172
171- rt = info -> do_op (r , p , src , dst );
173+ if (info -> do_op (r , p , src , dst , & rt ))
174+ goto out_test_failed ;
172175
173176 switch (bench_format ) {
174177 case BENCH_FORMAT_DEFAULT :
@@ -194,11 +197,11 @@ static void __bench_mem_function(struct bench_mem_info *info, struct bench_param
194197 break ;
195198 }
196199
200+ out_test_failed :
197201out_free :
198- free (src );
199- free (dst );
202+ if (r -> fn .fini ) r -> fn .fini (info , p , & src , & dst );
200203 return ;
201- out_alloc_failed :
204+ out_init_failed :
202205 printf ("# Memory allocation failed - maybe size (%s) is too large?\n" , size_str );
203206 goto out_free ;
204207}
@@ -265,8 +268,8 @@ static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
265268 fn (dst , src , size );
266269}
267270
268- static union bench_clock do_memcpy (const struct function * r , struct bench_params * p ,
269- void * src , void * dst )
271+ static int do_memcpy (const struct function * r , struct bench_params * p ,
272+ void * src , void * dst , union bench_clock * rt )
270273{
271274 union bench_clock start , end ;
272275 memcpy_t fn = r -> fn .memcpy ;
@@ -278,16 +281,47 @@ static union bench_clock do_memcpy(const struct function *r, struct bench_params
278281 fn (dst , src , p -> size );
279282 clock_get (& end );
280283
281- return clock_diff (& start , & end );
284+ * rt = clock_diff (& start , & end );
285+
286+ return 0 ;
287+ }
288+
289+ static bool mem_alloc (struct bench_mem_info * info , struct bench_params * p ,
290+ void * * src , void * * dst )
291+ {
292+ bool failed ;
293+
294+ * dst = zalloc (p -> size );
295+ failed = * dst == NULL ;
296+
297+ if (info -> alloc_src ) {
298+ * src = zalloc (p -> size );
299+ failed = failed || * src == NULL ;
300+ }
301+
302+ return failed ;
303+ }
304+
305+ static void mem_free (struct bench_mem_info * info __maybe_unused ,
306+ struct bench_params * p __maybe_unused ,
307+ void * * src , void * * dst )
308+ {
309+ free (* dst );
310+ free (* src );
311+
312+ * dst = * src = NULL ;
282313}
283314
284315struct function memcpy_functions [] = {
285316 { .name = "default" ,
286317 .desc = "Default memcpy() provided by glibc" ,
318+ .fn .init = mem_alloc ,
319+ .fn .fini = mem_free ,
287320 .fn .memcpy = memcpy },
288321
289322#ifdef HAVE_ARCH_X86_64_SUPPORT
290- # define MEMCPY_FN (_fn , _name , _desc ) {.name = _name , .desc = _desc , .fn .memcpy = _fn },
323+ # define MEMCPY_FN (_fn , _init , _fini , _name , _desc ) \
324+ {.name = _name , .desc = _desc , .fn .memcpy = _fn , .fn .init = _init , .fn .fini = _fini },
291325# include "mem-memcpy-x86-64-asm-def.h"
292326# undef MEMCPY_FN
293327#endif
@@ -312,8 +346,8 @@ int bench_mem_memcpy(int argc, const char **argv)
312346 return bench_mem_common (argc , argv , & info );
313347}
314348
315- static union bench_clock do_memset (const struct function * r , struct bench_params * p ,
316- void * src __maybe_unused , void * dst )
349+ static int do_memset (const struct function * r , struct bench_params * p ,
350+ void * src __maybe_unused , void * dst , union bench_clock * rt )
317351{
318352 union bench_clock start , end ;
319353 memset_t fn = r -> fn .memset ;
@@ -329,7 +363,9 @@ static union bench_clock do_memset(const struct function *r, struct bench_params
329363 fn (dst , i , p -> size );
330364 clock_get (& end );
331365
332- return clock_diff (& start , & end );
366+ * rt = clock_diff (& start , & end );
367+
368+ return 0 ;
333369}
334370
335371static const char * const bench_mem_memset_usage [] = {
@@ -340,10 +376,13 @@ static const char * const bench_mem_memset_usage[] = {
340376static const struct function memset_functions [] = {
341377 { .name = "default" ,
342378 .desc = "Default memset() provided by glibc" ,
379+ .fn .init = mem_alloc ,
380+ .fn .fini = mem_free ,
343381 .fn .memset = memset },
344382
345383#ifdef HAVE_ARCH_X86_64_SUPPORT
346- # define MEMSET_FN (_fn , _name , _desc ) { .name = _name , .desc = _desc , .fn .memset = _fn },
384+ # define MEMSET_FN (_fn , _init , _fini , _name , _desc ) \
385+ {.name = _name , .desc = _desc , .fn .memset = _fn , .fn .init = _init , .fn .fini = _fini },
347386# include "mem-memset-x86-64-asm-def.h"
348387# undef MEMSET_FN
349388#endif
0 commit comments