1/*
2 Copyright (c) 2005-2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#ifdef __cplusplus
18#error For testing purpose, this file should be compiled with a C compiler, not C++
19#endif /*__cplusplus */
20
21#include "tbb/scalable_allocator.h"
22#include <stdio.h>
23#include <assert.h>
24#include <stdlib.h> /* for atexit */
25
26/*
27 * The test is to check if the scalable_allocator.h and its functions
28 * can be used from pure C programs; also some regression checks are done
29 */
30
31#if __linux__
32/* huge pages supported only under Linux so far */
33const int ExpectedResultHugePages = TBBMALLOC_OK;
34#else
35const int ExpectedResultHugePages = TBBMALLOC_NO_EFFECT;
36#endif
37
38/* bool type definition for C */
39#if (defined(_MSC_VER) && _MSC_VER < 1800) || __sun || __SUNPRO_CC
40typedef int bool;
41#define false 0
42#define true 1
43#else
44#include <stdbool.h>
45#endif
46
47#if __TBB_SOURCE_DIRECTLY_INCLUDED
48#include "../tbbmalloc/tbbmalloc_internal_api.h"
49#else
50#define __TBB_mallocProcessShutdownNotification(bool)
51#endif
52
53/* test that it's possible to call allocation function from atexit
54 after mallocProcessShutdownNotification() called */
55static void MyExit(void) {
56 void *p = scalable_malloc(32);
57 assert(p);
58 scalable_free(p);
59 __TBB_mallocProcessShutdownNotification(false);
60}
61
62int main(void) {
63 size_t i, j;
64 int curr_mode, res;
65 void *p1, *p2;
66
67 atexit( MyExit );
68 for ( curr_mode = 0; curr_mode<=1; curr_mode++) {
69 assert(ExpectedResultHugePages ==
70 scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, !curr_mode));
71 p1 = scalable_malloc(10*1024*1024);
72 assert(p1);
73 assert(ExpectedResultHugePages ==
74 scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, curr_mode));
75 scalable_free(p1);
76 }
77 /* note that huge pages (if supported) are still enabled at this point */
78#if __TBB_SOURCE_DIRECTLY_INCLUDED
79 assert(TBBMALLOC_OK ==
80 scalable_allocation_mode(TBBMALLOC_INTERNAL_SOURCE_INCLUDED, 0));
81#endif
82
83 for( i=0; i<=1<<16; ++i) {
84 p1 = scalable_malloc(i);
85 if( !p1 )
86 printf("Warning: there should be memory but scalable_malloc returned NULL\n");
87 scalable_free(p1);
88 }
89 p1 = p2 = NULL;
90 for( i=1024*1024; ; i/=2 )
91 {
92 scalable_free(p1);
93 p1 = scalable_realloc(p2, i);
94 p2 = scalable_calloc(i, 32);
95 if (p2) {
96 if (i<sizeof(size_t)) {
97 for (j=0; j<i; j++)
98 assert(0==*((char*)p2+j));
99 } else {
100 for (j=0; j<i; j+=sizeof(size_t))
101 assert(0==*((size_t*)p2+j));
102 }
103 }
104 scalable_free(p2);
105 p2 = scalable_malloc(i);
106 if (i==0) break;
107 }
108 for( i=1; i<1024*1024; i*=2 )
109 {
110 scalable_free(p1);
111 p1 = scalable_realloc(p2, i);
112 p2 = scalable_malloc(i);
113 }
114 scalable_free(p1);
115 scalable_free(p2);
116 res = scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, NULL);
117 assert(res == TBBMALLOC_OK);
118 res = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS, NULL);
119 /* expect all caches cleaned before, so got nothing from CLEAN_THREAD_BUFFERS */
120 assert(res == TBBMALLOC_NO_EFFECT);
121 /* check that invalid param argument give expected result*/
122 res = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS,
123 (void*)(intptr_t)1);
124 assert(res == TBBMALLOC_INVALID_PARAM);
125 __TBB_mallocProcessShutdownNotification(false);
126 printf("done\n");
127 return 0;
128}
129