1/*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20#include "auto_zone.h"
21#include "auto_impl_utilities.h"
22#include <stdio.h>
23#include <string.h>
24#include <stdlib.h>
25
26
27#include <sys/time.h>
28#include <sys/resource.h>
29#define   RUSAGE_SELF     0
30
31static auto_zone_t *gc_zone;
32
33static void
34__invalidate(void *ptr, void *context)
35{
36	printf("invalidating space %p\n", ptr);
37}
38
39static void
40invalidate(auto_zone_t *zone, void* ptr, void *context)
41{
42	__invalidate(ptr, NULL);
43}
44
45static void
46batch_invalidate(auto_zone_t *zone, auto_zone_foreach_object_t foreach, auto_zone_cursor_t cursor)
47{
48    printf("batch_invalidate!\n");
49	foreach(cursor, __invalidate, NULL);
50}
51
52static boolean_t
53rb_gc_auto_should_collect(auto_zone_t *zone, const auto_statistics_t *stats, boolean_t about_to_create_new_region)
54{
55    return 0;
56}
57
58static void
59init_gc_zone(void)
60{
61    auto_collection_control_t *control;
62
63    gc_zone = auto_zone_create("sample collected zone");
64
65    control = auto_collection_parameters(gc_zone);
66    //control->invalidate = invalidate;
67    //control->should_collect = rb_gc_auto_should_collect;
68    //control->ask_should_collect_frequency = -1;
69    control->batch_invalidate = batch_invalidate;
70    control->disable_generational = 1;
71    control->log = AUTO_LOG_ALL;
72
73    auto_zone_register_thread(gc_zone);
74
75    //auto_collector_disable(gc_zone);
76}
77
78#define NOBJECTS 1000000
79int *pointers[NOBJECTS];
80
81static void
82allocate_objects(long n)
83{
84    long i;
85    //printf("allocate %ld objects\n", n);
86    for (i = 0; i < n; i++) {
87        pointers[i] = auto_zone_allocate_object(gc_zone, 100, AUTO_OBJECT_SCANNED, 1, 0);
88        pointers[i][0] = 10;
89    }
90}
91
92static void
93free_allocated_objects(long n) {
94    long i;
95    for (i = 0; i < n; ++i)
96        malloc_zone_free(gc_zone, pointers[i]);
97}
98
99static void
100malloc_objects(long n)
101{
102    long i;
103    //printf("malloc %ld pieces\n", n);
104    for (i = 0; i < n; i++) {
105        pointers[i] = malloc(100);
106        pointers[i][0] = 10;
107    }
108}
109static void
110free_objects(long n) {
111    long i;
112    for (i = 0; i < n; ++i)
113        free(pointers[i]);
114}
115
116static void
117collect(void)
118{
119    auto_collect(gc_zone, AUTO_COLLECT_FULL_COLLECTION, NULL);
120}
121
122void testmalloc(long n) {
123    malloc_objects(n);
124    //free_objects(n);
125}
126
127void testauto(long n) {
128    allocate_objects(n);
129    //free_objects(n);
130    //free_allocated_objects(n);
131}
132
133int main(int argc, char **argv)
134{
135    init_gc_zone();
136    int do_auto = 1;
137    int do_malloc = 1;
138    if (argc > 1) {
139        if (argv[1][0] == 'b') {
140            ;
141        }
142        else if (argv[1][0] == 'm') {
143            do_auto = 0;
144        }
145        else if (argv[1][0] == 'a') {
146            do_malloc = 0;
147        }
148    }
149    else {
150    }
151#if 1
152    if (do_auto) testauto(1);
153    if (do_malloc) testmalloc(1);
154#endif
155    auto_date_t overhead = auto_date_now();
156    auto_date_t begin = auto_date_now();
157    if (do_auto) testauto(NOBJECTS);
158    auto_date_t middle = auto_date_now();
159    if (do_malloc) testmalloc(NOBJECTS);
160    auto_date_t zend = auto_date_now();
161
162    printf("overhead %lld\n", begin-overhead);
163    printf("begin %lld\nafter auto %lld\nafter malloc %lld\n\n", begin, middle, zend);
164
165    printf("auto time   %lld\nmalloc time %lld\n", middle-begin, zend-middle);
166    printf("sum         %lld\n", middle-begin + zend-middle);
167    //collect();
168    //pause();
169	return 0;
170}
171