-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.h
79 lines (72 loc) · 2.78 KB
/
context.h
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
#pragma once
#include "config.h"
#include <functional>
#include <memory>
#include "error.h"
#include <string.h>
#if __linux__
#include <sys/mman.h>
#endif
namespace co
{
struct StackAllocator
{
static stack_malloc_fn_t& get_malloc_fn()
{
static stack_malloc_fn_t stack_malloc_fn = &::std::malloc;
return stack_malloc_fn;
}
static stack_free_fn_t& get_free_fn()
{
static stack_free_fn_t stack_free_fn = &::std::free;
return stack_free_fn;
}
static uint32_t& get_protect_stack_page()
{
static uint32_t protect_stack_page = 0;
return protect_stack_page;
}
#if __linux__
static bool protect_stack(void *top, std::size_t stack_size,
uint32_t page)
{
if (!page) return false;
if (stack_size <= getpagesize() * (page + 1))
ThrowError(eCoErrorCode::ec_protect_stack_failed);
void *protect_page_addr = ((std::size_t)top & 0xfff) ? (void*)(((std::size_t)top & ~(std::size_t)0xfff) + 0x1000) : top;
if (-1 == mprotect(protect_page_addr, getpagesize() * page, PROT_NONE)) {
DebugPrint(dbg_task, "origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u, protect stack top error: %s",
top, protect_page_addr, getpagesize(), page, strerror(errno));
return false;
} else {
DebugPrint(dbg_task, "origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u, protect stack success.",
top, protect_page_addr, page, getpagesize());
return true;
}
}
static void unprotect_stack(void *top, uint32_t page)
{
if (!page) return ;
void *protect_page_addr = ((std::size_t)top & 0xfff) ? (void*)(((std::size_t)top & ~(std::size_t)0xfff) + 0x1000) : top;
if (-1 == mprotect(protect_page_addr, getpagesize() * page, PROT_READ|PROT_WRITE)) {
DebugPrint(dbg_task, "origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u, protect stack top error: %s",
top, protect_page_addr, getpagesize(), page, strerror(errno));
} else {
DebugPrint(dbg_task, "origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u, protect stack success.",
top, protect_page_addr, page, getpagesize());
}
}
#endif
};
} //namespace co
#if USE_BOOST_COROUTINE
# include <libgo/ctx_boost_coroutine/context.h>
#elif USE_BOOST_CONTEXT
# include "ctx_boost_context/context.h"
#elif USE_UCONTEXT
# include <libgo/ctx_ucontext/context.h>
#elif USE_FIBER
# include <libgo/ctx_win_fiber/context.h>
#else
# error "No context sets."
#endif