Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/base/internal/low_level_alloc.h"
00016
00017 #include <stdint.h>
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <thread>
00021 #include <unordered_map>
00022 #include <utility>
00023
00024 namespace absl {
00025 namespace base_internal {
00026 namespace {
00027
00028
00029
00030 #define TEST_ASSERT(x) \
00031 if (!(x)) { \
00032 printf("TEST_ASSERT(%s) FAILED ON LINE %d\n", #x, __LINE__); \
00033 abort(); \
00034 }
00035
00036
00037 struct BlockDesc {
00038 char *ptr;
00039 int len;
00040 int fill;
00041 };
00042
00043
00044
00045 static void CheckBlockDesc(const BlockDesc &d) {
00046 for (int i = 0; i != d.len; i++) {
00047 TEST_ASSERT((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff));
00048 }
00049 }
00050
00051
00052
00053 static void RandomizeBlockDesc(BlockDesc *d) {
00054 d->fill = rand() & 0xff;
00055 for (int i = 0; i != d->len; i++) {
00056 d->ptr[i] = (d->fill + i) & 0xff;
00057 }
00058 }
00059
00060
00061
00062 static bool using_low_level_alloc = false;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static void Test(bool use_new_arena, bool call_malloc_hook, int n) {
00077 typedef std::unordered_map<int, BlockDesc> AllocMap;
00078 AllocMap allocated;
00079 AllocMap::iterator it;
00080 BlockDesc block_desc;
00081 int rnd;
00082 LowLevelAlloc::Arena *arena = 0;
00083 if (use_new_arena) {
00084 int32_t flags = call_malloc_hook ? LowLevelAlloc::kCallMallocHook : 0;
00085 arena = LowLevelAlloc::NewArena(flags);
00086 }
00087 for (int i = 0; i != n; i++) {
00088 if (i != 0 && i % 10000 == 0) {
00089 printf(".");
00090 fflush(stdout);
00091 }
00092
00093 switch (rand() & 1) {
00094 case 0:
00095 using_low_level_alloc = true;
00096 block_desc.len = rand() & 0x3fff;
00097 block_desc.ptr =
00098 reinterpret_cast<char *>(
00099 arena == 0
00100 ? LowLevelAlloc::Alloc(block_desc.len)
00101 : LowLevelAlloc::AllocWithArena(block_desc.len, arena));
00102 using_low_level_alloc = false;
00103 RandomizeBlockDesc(&block_desc);
00104 rnd = rand();
00105 it = allocated.find(rnd);
00106 if (it != allocated.end()) {
00107 CheckBlockDesc(it->second);
00108 using_low_level_alloc = true;
00109 LowLevelAlloc::Free(it->second.ptr);
00110 using_low_level_alloc = false;
00111 it->second = block_desc;
00112 } else {
00113 allocated[rnd] = block_desc;
00114 }
00115 break;
00116 case 1:
00117 it = allocated.begin();
00118 if (it != allocated.end()) {
00119 CheckBlockDesc(it->second);
00120 using_low_level_alloc = true;
00121 LowLevelAlloc::Free(it->second.ptr);
00122 using_low_level_alloc = false;
00123 allocated.erase(it);
00124 }
00125 break;
00126 }
00127 }
00128
00129 while ((it = allocated.begin()) != allocated.end()) {
00130 CheckBlockDesc(it->second);
00131 using_low_level_alloc = true;
00132 LowLevelAlloc::Free(it->second.ptr);
00133 using_low_level_alloc = false;
00134 allocated.erase(it);
00135 }
00136 if (use_new_arena) {
00137 TEST_ASSERT(LowLevelAlloc::DeleteArena(arena));
00138 }
00139 }
00140
00141
00142 static struct BeforeMain {
00143 BeforeMain() {
00144 Test(false, false, 50000);
00145 Test(true, false, 50000);
00146 Test(true, true, 50000);
00147 }
00148 } before_main;
00149
00150 }
00151 }
00152 }
00153
00154 int main(int argc, char *argv[]) {
00155
00156 printf("PASS\n");
00157 return 0;
00158 }