blob: 0a00f00935de19c3a5ec3bb78b23d01ed091dd5d [file] [log] [blame]
Mike Klein58b13062016-11-11 10:38:49 -05001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
9#include "SkFixedAlloc.h"
10
11namespace {
12
13 static int created, destroyed;
14
15 struct Foo {
16 Foo(int X, float Y) : x(X), y(Y) { created++; }
17 ~Foo() { destroyed++; }
18
19 int x;
20 float y;
21 };
22
23 struct Big {
24 Big() {}
25 uint32_t array[128];
26 };
27
28}
29
30DEF_TEST(FixedAlloc, r) {
31 // Basic mechanics.
32 {
33 uint8_t buf[128];
34 SkFixedAlloc fa(buf, sizeof(buf));
35
36 Foo* foo = fa.make<Foo>(3, 4.0f);
37 REPORTER_ASSERT(r, foo);
38 REPORTER_ASSERT(r, foo->x == 3);
39 REPORTER_ASSERT(r, foo->y == 4.0f);
40 REPORTER_ASSERT(r, created == 1);
41 REPORTER_ASSERT(r, destroyed == 0);
42
43 Foo* bar = fa.make<Foo>(8, 1.0f);
44 REPORTER_ASSERT(r, bar);
45 REPORTER_ASSERT(r, bar->x == 8);
46 REPORTER_ASSERT(r, bar->y == 1.0f);
47 REPORTER_ASSERT(r, created == 2);
48 REPORTER_ASSERT(r, destroyed == 0);
49
50 fa.undo();
51 REPORTER_ASSERT(r, created == 2);
52 REPORTER_ASSERT(r, destroyed == 1);
53 }
54 REPORTER_ASSERT(r, created == 2);
55 REPORTER_ASSERT(r, destroyed == 2);
56
57 {
58 // Test alignment gurantees.
59 uint8_t buf[64];
60 SkFixedAlloc fa(buf+3, sizeof(buf)-3);
61
62 Foo* foo = fa.make<Foo>(3, 4.0f);
63 REPORTER_ASSERT(r, SkIsAlign4((uintptr_t)foo));
64 REPORTER_ASSERT(r, created == 3);
65 REPORTER_ASSERT(r, destroyed == 2);
66
67 // Might as well test reset() while we're at it.
68 fa.reset();
69 REPORTER_ASSERT(r, created == 3);
70 REPORTER_ASSERT(r, destroyed == 3);
71 }
72 REPORTER_ASSERT(r, created == 3);
73 REPORTER_ASSERT(r, destroyed == 3);
74}
75
76DEF_TEST(FallbackAlloc, r) {
77 // SkFixedAlloc will eventually fail when it runs out of space in its buffer.
78 int buf[32];
79 SkFixedAlloc fixed(buf, sizeof(buf));
80 bool fixed_failed = false;
81 for (int i = 0; i < 32; i++) {
82 // (Remember, there is some overhead to each make() call.)
83 fixed_failed = fixed_failed || (fixed.make<int>(i) == nullptr);
84 }
85 REPORTER_ASSERT(r, fixed_failed);
86
87
88 // SkFallbackAlloc will always succeed, using the heap as required.
89 fixed.reset();
90 SkFallbackAlloc fallback(&fixed);
91
92 bool fallback_failed = false;
93 for (int i = 0; i < 32; i++) {
94 fallback_failed = fallback_failed || (fallback.make<int>(i) == nullptr);
95 }
96 REPORTER_ASSERT(r, !fallback_failed);
97
98
99 // Test small, big, small allocations to make sure once we go to the heap we stay there.
100 fallback.reset();
101 auto smallA = fallback.make<int>(2);
102 auto big = fallback.make<Big>();
103 auto smallB = fallback.make<int>(3);
104
105 auto in_buf = [&](void* ptr) {
106 return (uintptr_t)(buf+0 ) <= (uintptr_t)ptr
107 && (uintptr_t)(buf+32) > (uintptr_t)ptr;
108 };
109
110 REPORTER_ASSERT(r, in_buf(smallA));
111 REPORTER_ASSERT(r, !in_buf(big));
112 REPORTER_ASSERT(r, !in_buf(smallB));
113}