-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
fiber_stack.c
98 lines (76 loc) · 2.44 KB
/
fiber_stack.c
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
/*
+--------------------------------------------------------------------+
| ext-fiber |
+--------------------------------------------------------------------+
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the conditions mentioned |
| in the accompanying LICENSE file are met. |
+--------------------------------------------------------------------+
| Authors: Martin Schröder <m.schroeder2007@gmail.com> |
| Aaron Piotrowski <aaron@trowski.com> |
+--------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "zend.h"
#include "fiber_stack.h"
#ifdef HAVE_VALGRIND
#include "valgrind/valgrind.h"
#endif
zend_bool zend_fiber_stack_allocate(zend_fiber_stack *stack, unsigned int size)
{
size_t msize;
stack->size = ((size_t) size + ZEND_FIBER_PAGESIZE - 1) / ZEND_FIBER_PAGESIZE * ZEND_FIBER_PAGESIZE;
#ifdef ZEND_FIBER_MMAP
void *pointer;
int mapflags = MAP_PRIVATE | MAP_ANONYMOUS;
#ifdef __OpenBSD__
mapflags |= MAP_STACK;
#endif
msize = stack->size + ZEND_FIBER_GUARD_PAGES * ZEND_FIBER_PAGESIZE;
pointer = mmap(0, msize, PROT_READ | PROT_WRITE, mapflags, -1, 0);
if (pointer == (void *) -1) {
return 0;
}
#if ZEND_FIBER_GUARD_PAGES
mprotect(pointer, ZEND_FIBER_GUARD_PAGES * ZEND_FIBER_PAGESIZE, PROT_NONE);
#endif
stack->pointer = (void *)((char *) pointer + ZEND_FIBER_GUARD_PAGES * ZEND_FIBER_PAGESIZE);
#else
stack->pointer = emalloc_large(stack->size);
msize = stack->size;
#endif
if (!stack->pointer) {
return 0;
}
#ifdef VALGRIND_STACK_REGISTER
char * base;
base = (char *) stack->pointer;
stack->valgrind = VALGRIND_STACK_REGISTER(base, base + msize - ZEND_FIBER_GUARD_PAGES * ZEND_FIBER_PAGESIZE);
#endif
return 1;
}
void zend_fiber_stack_free(zend_fiber_stack *stack)
{
if (stack->pointer != NULL) {
#ifdef VALGRIND_STACK_DEREGISTER
VALGRIND_STACK_DEREGISTER(stack->valgrind);
#endif
#ifdef ZEND_FIBER_MMAP
void *address;
size_t len;
address = (void *)((char *) stack->pointer - ZEND_FIBER_GUARD_PAGES * ZEND_FIBER_PAGESIZE);
len = stack->size + ZEND_FIBER_GUARD_PAGES * ZEND_FIBER_PAGESIZE;
munmap(address, len);
#else
efree(stack->pointer);
#endif
stack->pointer = NULL;
}
}
/*
* vim: sw=4 ts=4
* vim600: fdm=marker
*/