Init Repo

This commit is contained in:
root
2019-09-06 23:53:10 +08:00
commit f0ef89dfbb
7905 changed files with 914138 additions and 0 deletions

182
vendor/swoole/src/coroutine/base.cc vendored Executable file
View File

@@ -0,0 +1,182 @@
#include "coroutine.h"
#include "context.h"
#include <string>
/* allocate cid for coroutine */
typedef struct cidmap
{
uint32_t nr_free;
char page[65536];
} cidmap_t;
using namespace swoole;
struct coroutine_s
{
public:
Context ctx;
int cid;
coroutine_s(int _cid, size_t stack_size, coroutine_func_t fn, void* private_data) :
ctx(stack_size, fn, private_data)
{
cid = _cid;
}
};
static struct
{
int stack_size;
int current_cid;
int previous_cid;
struct coroutine_s *coroutines[MAX_CORO_NUM_LIMIT + 1];
coroutine_close_t onClose;
} swCoroG =
{ SW_DEFAULT_C_STACK_SIZE, -1, -1,
{ NULL, }, NULL };
/* 1 <= cid <= 524288 */
static cidmap_t cidmap =
{ MAX_CORO_NUM_LIMIT,
{ 0 } };
static int last_cid = -1;
static inline int test_and_set_bit(int cid, void *addr)
{
uint32_t mask = 1U << (cid & 0x1f);
uint32_t *p = ((uint32_t*) addr) + (cid >> 5);
uint32_t old = *p;
*p = old | mask;
return (old & mask) == 0;
}
static inline void clear_bit(int cid, void *addr)
{
uint32_t mask = 1U << (cid & 0x1f);
uint32_t *p = ((uint32_t*) addr) + (cid >> 5);
uint32_t old = *p;
*p = old & ~mask;
}
/* find next free cid */
static inline int find_next_zero_bit(void *addr, int cid)
{
uint32_t *p;
uint32_t mask;
int mark = cid;
cid++;
cid &= 0x7ffff;
while (cid != mark)
{
mask = 1U << (cid & 0x1f);
p = ((uint32_t*) addr) + (cid >> 5);
if ((~(*p) & mask))
{
break;
}
++cid;
cid &= 0x7fff;
}
return cid;
}
static inline int alloc_cidmap()
{
int cid;
if (cidmap.nr_free == 0)
{
return -1;
}
cid = find_next_zero_bit(&cidmap.page, last_cid);
if (test_and_set_bit(cid, &cidmap.page))
{
--cidmap.nr_free;
last_cid = cid;
return cid + 1;
}
return -1;
}
static inline void free_cidmap(int cid)
{
cid--;
cidmap.nr_free++;
clear_bit(cid, &cidmap.page);
}
int coroutine_create(coroutine_func_t fn, void* args)
{
int cid = alloc_cidmap();
if (unlikely(cid == -1))
{
swWarn("alloc_cidmap failed");
return CORO_LIMIT;
}
coroutine_t *co = new coroutine_t(cid, swCoroG.stack_size, fn, args);
swCoroG.coroutines[cid] = co;
swCoroG.previous_cid = swCoroG.current_cid;
swCoroG.current_cid = cid;
co->ctx.SwapIn();
if (co->ctx.end)
{
if (swCoroG.onClose)
{
swCoroG.onClose();
}
coroutine_release(co);
}
return cid;
}
void coroutine_yield(coroutine_t *co)
{
swCoroG.current_cid = swCoroG.previous_cid;
co->ctx.SwapOut();
}
void coroutine_resume(coroutine_t *co)
{
swCoroG.previous_cid = swCoroG.current_cid;
swCoroG.current_cid = co->cid;
co->ctx.SwapIn();
if (co->ctx.end)
{
if (swCoroG.onClose)
{
swCoroG.onClose();
}
coroutine_release(co);
}
}
void coroutine_release(coroutine_t *co)
{
free_cidmap(co->cid);
swCoroG.coroutines[co->cid] = NULL;
delete co;
}
void coroutine_set_close(coroutine_close_t func)
{
swCoroG.onClose = func;
}
coroutine_t* coroutine_get_by_id(int cid)
{
return swCoroG.coroutines[cid];
}
int coroutine_get_cid()
{
return swCoroG.current_cid;
}

76
vendor/swoole/src/coroutine/boost.cc vendored Executable file
View File

@@ -0,0 +1,76 @@
#include "swoole.h"
#include "context.h"
#if USE_BOOST_CONTEXT
using namespace swoole;
Context::Context(size_t stack_size, coroutine_func_t fn, void* private_data) :
fn_(fn), stack_size_(stack_size), private_data_(private_data)
{
BOOST_ASSERT(boost::context::stack_traits::minimum_size() <= stack_size_);
BOOST_ASSERT(
boost::context::stack_traits::is_unbounded()
|| (boost::context::stack_traits::maximum_size() >= stack_size_));
protect_page_ = 0;
end = false;
swap_ctx_ = NULL;
stack_ = (char*) sw_malloc(stack_size_);
swDebug("alloc stack: size=%u, ptr=%p.", stack_size_, stack_);
void* sp = (void*) ((char*) stack_ + stack_size_);
#ifdef USE_VALGRIND
valgrind_stack_id = VALGRIND_STACK_REGISTER(sp, stack_);
#endif
ctx_ = boost::context::make_fcontext(sp, stack_size_, (void (*)(intptr_t))&context_func);
uint32_t protect_page = get_protect_stack_page();
if (protect_page)
{
if (protect_stack(stack_, stack_size_, protect_page))
{
protect_page_ = protect_page;
}
}
}
Context::~Context()
{
if (stack_)
{
swDebug("free stack: ptr=%p", stack_);
if (protect_page_)
{
unprotect_stack(stack_, protect_page_);
}
#if defined(USE_VALGRIND)
VALGRIND_STACK_DEREGISTER(valgrind_stack_id);
#endif
sw_free(stack_);
stack_ = NULL;
}
}
bool Context::SwapIn()
{
boost::context::jump_fcontext(&swap_ctx_, ctx_, (intptr_t) this, true);
return true;
}
bool Context::SwapOut()
{
boost::context::jump_fcontext(&ctx_, swap_ctx_, (intptr_t) this, true);
return true;
}
void Context::context_func(void *arg)
{
Context* _this = (Context*) arg;
_this->fn_(_this->private_data_);
_this->end = true;
_this->SwapOut();
}
#endif

71
vendor/swoole/src/coroutine/context.cc vendored Executable file
View File

@@ -0,0 +1,71 @@
#include "swoole.h"
#include "context.h"
#ifndef SW_NO_USE_ASM_CONTEXT
using namespace swoole;
Context::Context(size_t stack_size, coroutine_func_t fn, void* private_data) :
fn_(fn), stack_size_(stack_size), private_data_(private_data)
{
protect_page_ = 0;
end = false;
swap_ctx_ = NULL;
stack_ = (char*) sw_malloc(stack_size_);
swDebug("alloc stack: size=%u, ptr=%p.", stack_size_, stack_);
void* sp = (void*) ((char*) stack_ + stack_size_);
#ifdef USE_VALGRIND
valgrind_stack_id = VALGRIND_STACK_REGISTER(sp, stack_);
#endif
ctx_ = make_fcontext(sp, stack_size_, (void (*)(intptr_t))&context_func);
uint32_t protect_page = get_protect_stack_page();
if (protect_page)
{
if (protect_stack(stack_, stack_size_, protect_page))
{
protect_page_ = protect_page;
}
}
}
Context::~Context()
{
if (stack_)
{
swDebug("free stack: ptr=%p", stack_);
if (protect_page_)
{
unprotect_stack(stack_, protect_page_);
}
#if defined(USE_VALGRIND)
VALGRIND_STACK_DEREGISTER(valgrind_stack_id);
#endif
sw_free(stack_);
stack_ = NULL;
}
}
bool Context::SwapIn()
{
jump_fcontext(&swap_ctx_, ctx_, (intptr_t) this, true);
return true;
}
bool Context::SwapOut()
{
jump_fcontext(&ctx_, swap_ctx_, (intptr_t) this, true);
return true;
}
void Context::context_func(void *arg)
{
Context *_this = (Context *) arg;
_this->fn_(_this->private_data_);
_this->end = true;
_this->SwapOut();
}
#endif

79
vendor/swoole/src/coroutine/ucontext.cc vendored Executable file
View File

@@ -0,0 +1,79 @@
#include "swoole.h"
#include "context.h"
#if USE_UCONTEXT
using namespace swoole;
Context::Context(size_t stack_size, coroutine_func_t fn, void* private_data) :
fn_(fn), stack_size_(stack_size), private_data_(private_data)
{
if (-1 == getcontext(&ctx_))
{
swoole_throw_error(SW_ERROR_CO_GETCONTEXT_FAILED);
return;
}
protect_page_ = 0;
end = false;
stack_ = (char*) sw_malloc(stack_size);
swDebug("alloc stack: size=%lu, ptr=%p", stack_size, stack_);
ctx_.uc_stack.ss_sp = stack_;
ctx_.uc_stack.ss_size = stack_size;
ctx_.uc_link = NULL;
#if defined(USE_VALGRIND)
valgrind_stack_id = VALGRIND_STACK_REGISTER(static_cast<char *>(stack_) + stack_size, stack_);
#endif
makecontext(&ctx_, (void (*)(void))&context_func, 1, this);
uint32_t protect_page = get_protect_stack_page();
if (protect_page)
{
if (protect_stack(stack_, stack_size, protect_page))
{
protect_page_ = protect_page;
}
}
}
Context::~Context()
{
if (stack_)
{
swDebug("free stack: ptr=%p", stack_);
if (protect_page_)
{
unprotect_stack(stack_, protect_page_);
}
#if defined(USE_VALGRIND)
VALGRIND_STACK_DEREGISTER(valgrind_stack_id);
#endif
sw_free(stack_);
stack_ = NULL;
}
}
bool Context::SwapIn()
{
return 0 == swapcontext(&swap_ctx_, &ctx_);
}
bool Context::SwapOut()
{
return 0 == swapcontext(&ctx_, &swap_ctx_);
}
void Context::context_func(void *arg)
{
Context *_this = (Context *) arg;
_this->fn_(_this->private_data_);
_this->end = true;
_this->SwapOut();
}
#endif