File: stack_allocation-t.c

package info (click to toggle)
mariadb 1%3A11.8.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 772,520 kB
  • sloc: ansic: 2,414,714; cpp: 1,791,394; asm: 381,336; perl: 62,905; sh: 49,647; pascal: 40,897; java: 39,363; python: 20,791; yacc: 20,432; sql: 17,907; xml: 12,344; ruby: 8,544; cs: 6,542; makefile: 6,145; ada: 1,879; lex: 1,193; javascript: 996; objc: 80; tcl: 73; awk: 46; php: 22
file content (119 lines) | stat: -rw-r--r-- 3,662 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* Copyright (c) 2024, MariaDB Corporation.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA */

#include <my_global.h>
#include <my_sys.h>
#include <my_stack_alloc.h>
#include <my_pthread.h>
#include <my_alloca.h>
#include <tap.h>

/*
  Test of stack detection
  The test is run with a stacks of STACK_ALLOC_SMALL_BLOCK_SIZE+1 and
  STACK_ALLOC_SMALL_BLOCK_SIZE-1.
  This is becasue of the function alloc_on_stack() has
  different limits of how much it will allocate from the stack
  based on the allocation size.
*/

/*
  Common stack size in MariaDB. Cannot be bigger than system default
  stack (common is 8M)
*/
size_t my_stack_size= 299008;
size_t stack_allocation_total= 0;
extern long call_counter;
long call_counter;

ATTRIBUTE_NOINLINE
int test_stack(void *stack_start, void *stack_end, int iteration, size_t stack_allocation)
{
  void *res, *stack;
  my_bool must_be_freed;

  stack= my_get_stack_pointer(&must_be_freed);
  if (stack_start < stack_end)
  {
    if (stack < stack_start || stack > stack_end)
      return 1;
  }
  else
  {
    if (stack < stack_end || stack > stack_start)
      return 1;
  }
  alloc_on_stack(stack_end, res, must_be_freed, stack_allocation);
  bfill(res, stack_allocation, (char) iteration);
  if (!must_be_freed)
  {
    stack_allocation_total+= stack_allocation;
    test_stack(stack_start, stack_end, iteration+1, stack_allocation);
  }
  else
    my_free(res);              /* Was allocated with my_malloc */
  call_counter++;              /* Avoid tail recursion optimization */
  return 0;
}

void test_stack_detection(int stage, size_t stack_allocation)
{
  void *stack_start, *stack_end;
  int res;
  my_get_stack_bounds(&stack_start, &stack_end,
                      (void*) &stack_start, my_stack_size);
  stack_allocation_total= 0;
  res= test_stack(stack_start, stack_end, 1, stack_allocation);
  if (!res)
    ok(1, "%llu bytes allocated on stack of size %ld with %lu alloc size",
       (unsigned long long) stack_allocation_total,
       (long) available_stack_size(stack_start, stack_end),
       (unsigned long) stack_allocation);
  else
    ok(0, "stack checking failed");
}

pthread_handler_t thread_stack_check(void *arg __attribute__((unused)))
{
  my_thread_init();
  test_stack_detection(1, STACK_ALLOC_SMALL_BLOCK_SIZE-1);
  test_stack_detection(2, STACK_ALLOC_SMALL_BLOCK_SIZE+1);
  my_thread_end();
  return 0;
}

int main(int argc __attribute__((unused)), char **argv)
{
  pthread_attr_t thr_attr;
  pthread_t check_thread;
  void *value;

  MY_INIT(argv[0]);

  plan(4);
  test_stack_detection(3, STACK_ALLOC_SMALL_BLOCK_SIZE-1);
  test_stack_detection(4, STACK_ALLOC_SMALL_BLOCK_SIZE+1);

  /* Create a thread and run the same test */
  (void) pthread_attr_init(&thr_attr);
  pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
  (void) my_setstacksize(&thr_attr, my_stack_size);
  pthread_create(&check_thread, &thr_attr, thread_stack_check, 0);
  pthread_join(check_thread, &value);
  (void) pthread_attr_destroy(&thr_attr);

  my_end(0);
  return exit_status();
}