diff options
Diffstat (limited to 'accel-pptpd/triton')
-rw-r--r-- | accel-pptpd/triton/md.c | 6 | ||||
-rw-r--r-- | accel-pptpd/triton/timer.c | 6 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.c | 172 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.h | 17 | ||||
-rw-r--r-- | accel-pptpd/triton/triton_p.h | 27 |
5 files changed, 151 insertions, 77 deletions
diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c index 3cb47a6d..05d814cc 100644 --- a/accel-pptpd/triton/md.c +++ b/accel-pptpd/triton/md.c @@ -86,16 +86,16 @@ static void *md_thread(void *arg) return NULL; } -void __export triton_md_register_handler(struct triton_ctx_t *ctx, struct triton_md_handler_t *ud) +void __export triton_md_register_handler(struct triton_context_t *ctx, struct triton_md_handler_t *ud) { struct _triton_md_handler_t *h = mempool_alloc(md_pool); memset(h, 0, sizeof(*h)); h->ud = ud; h->epoll_event.data.ptr = h; if (ctx) - h->ctx = (struct _triton_ctx_t *)ctx->tpd; + h->ctx = (struct _triton_context_t *)ctx->tpd; else - h->ctx = (struct _triton_ctx_t *)default_ctx->tpd; + h->ctx = (struct _triton_context_t *)default_ctx->tpd; ud->tpd = h; spin_lock(&h->ctx->lock); list_add_tail(&h->entry, &h->ctx->handlers); diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c index f34c19d1..e9fd66a0 100644 --- a/accel-pptpd/triton/timer.c +++ b/accel-pptpd/triton/timer.c @@ -86,7 +86,7 @@ void *timer_thread(void *arg) return NULL; } -int __export triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t *ud, int abs_time) +int __export triton_timer_add(struct triton_context_t *ctx, struct triton_timer_t *ud, int abs_time) { struct _triton_timer_t *t = mempool_alloc(timer_pool); @@ -95,9 +95,9 @@ int __export triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t *u t->epoll_event.data.ptr = t; t->epoll_event.events = EPOLLIN | EPOLLET; if (ctx) - t->ctx = (struct _triton_ctx_t *)ctx->tpd; + t->ctx = (struct _triton_context_t *)ctx->tpd; else - t->ctx = (struct _triton_ctx_t *)default_ctx->tpd; + t->ctx = (struct _triton_context_t *)default_ctx->tpd; t->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if (t->fd < 0) { triton_log_error("timer:timerfd_create: %s" ,strerror(errno)); diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index 9aa7462b..ba08c122 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -7,7 +7,7 @@ #include "triton_p.h" -int thread_count = 4; +int thread_count = 1; int max_events = 64; static spinlock_t threads_lock = SPINLOCK_INITIALIZER; @@ -19,7 +19,7 @@ static LIST_HEAD(ctx_queue); static spinlock_t ctx_list_lock = SPINLOCK_INITIALIZER; static LIST_HEAD(ctx_list); -struct triton_ctx_t *default_ctx; +struct triton_context_t *default_ctx; static int terminate; static mempool_t *ctx_pool; @@ -31,61 +31,25 @@ void triton_thread_wakeup(struct _triton_thread_t *thread) static void* triton_thread(struct _triton_thread_t *thread) { - struct _triton_md_handler_t *h; - struct _triton_timer_t *t; sigset_t set; int sig; - uint64_t tt; sigemptyset(&set); sigaddset(&set, SIGUSR1); sigaddset(&set, SIGQUIT); - while(1){ + while (1) { sigwait(&set, &sig); cont: - if (thread->ctx->need_close) { - if (thread->ctx->ud->close) - thread->ctx->ud->close(thread->ctx->ud); - thread->ctx->need_close = 0; - } - - while (1) { - spin_lock(&thread->ctx->lock); - if (!list_empty(&thread->ctx->pending_timers)) { - t = list_entry(thread->ctx->pending_timers.next, typeof(*t), entry2); - list_del(&t->entry2); - t->pending = 0; - spin_unlock(&thread->ctx->lock); - read(t->fd, &tt, sizeof(tt)); - t->ud->expire(t->ud); - } - if (!list_empty(&thread->ctx->pending_handlers)) { - h = list_entry(thread->ctx->pending_handlers.next, typeof(*h), entry2); - list_del(&h->entry2); - h->pending = 0; - spin_unlock(&thread->ctx->lock); - - if (h->trig_epoll_events & (EPOLLIN | EPOLLERR | EPOLLHUP)) - if (h->ud->read) - if (h->ud->read(h->ud)) - continue; - if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) - if (h->ud->write) - if (h->ud->write(h->ud)) - continue; - h->trig_epoll_events = 0; - continue; - } - thread->ctx->thread = NULL; - spin_unlock(&thread->ctx->lock); - if (thread->ctx->need_free) - mempool_free(thread->ctx); - thread->ctx = NULL; - break; + if (swapcontext(&thread->uctx, &thread->ctx->uctx)) { + triton_log_error("swapcontext: %s\n", strerror(errno)); } + if (thread->ctx->need_free) + mempool_free(thread->ctx); + thread->ctx = NULL; + spin_lock(&threads_lock); if (!list_empty(&ctx_queue)) { thread->ctx = list_entry(ctx_queue.next, typeof(*thread->ctx), entry2); @@ -106,6 +70,55 @@ cont: } } +static void ctx_thread(struct _triton_context_t *ctx) +{ + struct _triton_md_handler_t *h; + struct _triton_timer_t *t; + uint64_t tt; + ucontext_t *uctx; + + while (1) { + uctx = &ctx->thread->uctx; + if (ctx->need_close) { + if (ctx->ud->close) + ctx->ud->close(ctx->ud); + ctx->need_close = 0; + } + + while (1) { + spin_lock(&ctx->lock); + if (!list_empty(&ctx->pending_timers)) { + t = list_entry(ctx->pending_timers.next, typeof(*t), entry2); + list_del(&t->entry2); + t->pending = 0; + spin_unlock(&ctx->lock); + read(t->fd, &tt, sizeof(tt)); + t->ud->expire(t->ud); + continue; + } + if (!list_empty(&ctx->pending_handlers)) { + h = list_entry(ctx->pending_handlers.next, typeof(*h), entry2); + list_del(&h->entry2); + h->pending = 0; + spin_unlock(&ctx->lock); + if (h->trig_epoll_events & (EPOLLIN | EPOLLERR | EPOLLHUP)) + if (h->ud && h->ud->read) + h->ud->read(h->ud); + if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) + if (h->ud && h->ud->write) + h->ud->write(h->ud); + h->trig_epoll_events = 0; + continue; + } + ctx->thread = NULL; + spin_unlock(&ctx->lock); + + if (swapcontext(&ctx->uctx, uctx)) + triton_log_error("swapcontext: %s\n", strerror(errno)); + } + } +} + struct _triton_thread_t *create_thread() { struct _triton_thread_t *thread = malloc(sizeof(*thread)); @@ -121,9 +134,9 @@ struct _triton_thread_t *create_thread() return thread; } -int triton_queue_ctx(struct _triton_ctx_t *ctx) +int triton_queue_ctx(struct _triton_context_t *ctx) { - if (ctx->thread || ctx->queued) + if (ctx->thread || ctx->queued || ctx->sleeping) return 0; spin_lock(&threads_lock); @@ -142,9 +155,9 @@ int triton_queue_ctx(struct _triton_ctx_t *ctx) return 1; } -void __export triton_register_ctx(struct triton_ctx_t *ud) +int __export triton_context_register(struct triton_context_t *ud) { - struct _triton_ctx_t *ctx = mempool_alloc(ctx_pool); + struct _triton_context_t *ctx = mempool_alloc(ctx_pool); memset(ctx, 0, sizeof(*ctx)); ctx->ud = ud; @@ -154,16 +167,33 @@ void __export triton_register_ctx(struct triton_ctx_t *ud) INIT_LIST_HEAD(&ctx->pending_handlers); INIT_LIST_HEAD(&ctx->pending_timers); + if (getcontext(&ctx->uctx)) { + triton_log_error("getcontext: %s\n", strerror(errno)); + free(ctx); + return -1; + } + + ctx->uctx.uc_stack.ss_size = CTX_STACK_SIZE; + ctx->uctx.uc_stack.ss_sp = malloc(CTX_STACK_SIZE); + if (!ctx->uctx.uc_stack.ss_sp) { + triton_log_error("out of memory\n"); + free(ctx); + return -1; + } + makecontext(&ctx->uctx, (void (*)())ctx_thread, 1, ctx); + ud->tpd = ctx; spin_lock(&ctx_list_lock); list_add_tail(&ctx->entry, &ctx_list); spin_unlock(&ctx_list_lock); + + return 0; } -void __export triton_unregister_ctx(struct triton_ctx_t *ud) +void __export triton_context_unregister(struct triton_context_t *ud) { - struct _triton_ctx_t *ctx = (struct _triton_ctx_t *)ud->tpd; + struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; if (!list_empty(&ctx->handlers)) { triton_log_error("BUG:ctx:triton_unregister_ctx: handlers is not empty"); @@ -175,6 +205,14 @@ void __export triton_unregister_ctx(struct triton_ctx_t *ud) } if (!list_empty(&ctx->timers)) { triton_log_error("BUG:ctx:triton_unregister_ctx: timers is not empty"); + { + struct _triton_timer_t *t; + while(!list_empty(&ctx->timers)) { + t = list_entry(ctx->timers.next, typeof(*t), entry); + t->ud->expire(t->ud); + list_del(&t->entry); + } + } abort(); } if (!list_empty(&ctx->pending_timers)) { @@ -187,17 +225,43 @@ void __export triton_unregister_ctx(struct triton_ctx_t *ud) list_del(&ctx->entry); spin_unlock(&ctx_list_lock); } +void __export triton_context_schedule(struct triton_context_t *ud) +{ + struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; + ucontext_t *uctx = &ctx->thread->uctx; + + spin_lock(&ctx->lock); + ctx->sleeping = 1; + ctx->thread = NULL; + spin_unlock(&ctx->lock); + + if (swapcontext(&ctx->uctx, uctx)) + triton_log_error("swaswpntext: %s\n", strerror(errno)); +} + +void __export triton_context_wakeup(struct triton_context_t *ud) +{ + struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; + int r; + + spin_lock(&ctx->lock); + ctx->sleeping = 0; + r = triton_queue_ctx(ctx); + spin_unlock(&ctx->lock); + if (r) + triton_thread_wakeup(ctx->thread); +} int __export triton_init(const char *conf_file, const char *mod_sect) { - ctx_pool = mempool_create(sizeof(struct _triton_ctx_t)); + ctx_pool = mempool_create(sizeof(struct _triton_context_t)); default_ctx = malloc(sizeof(*default_ctx)); if (!default_ctx) { fprintf(stderr,"cann't allocate memory\n"); return -1; } - triton_register_ctx(default_ctx); + triton_context_register(default_ctx); if (conf_load(conf_file)) return -1; @@ -237,7 +301,7 @@ void __export triton_run() void __export triton_terminate() { - struct _triton_ctx_t *ctx; + struct _triton_context_t *ctx; struct _triton_thread_t *t; md_terminate(); diff --git a/accel-pptpd/triton/triton.h b/accel-pptpd/triton/triton.h index 2cc5ccf6..735264a8 100644 --- a/accel-pptpd/triton/triton.h +++ b/accel-pptpd/triton/triton.h @@ -5,11 +5,11 @@ #include "list.h" -struct triton_ctx_t +struct triton_context_t { const void *tpd; // triton private data, don't touch! - void (*close)(struct triton_ctx_t*); - void (*free)(struct triton_ctx_t*); + void (*close)(struct triton_context_t*); + void (*free)(struct triton_context_t*); }; struct triton_md_handler_t @@ -41,18 +41,19 @@ struct conf_sect_t struct list_head items; }; -void triton_register_ctx(struct triton_ctx_t *); -void triton_unregister_ctx(struct triton_ctx_t *); -void triton_ctx_schedule(struct triton_md_handler_t *, struct triton_timer_t *); +int triton_context_register(struct triton_context_t *); +void triton_context_unregister(struct triton_context_t *); +void triton_context_schedule(struct triton_context_t *); +void triton_context_wakeup(struct triton_context_t *); #define MD_MODE_READ 1 #define MD_MODE_WRITE 2 -void triton_md_register_handler(struct triton_ctx_t *, struct triton_md_handler_t *); +void triton_md_register_handler(struct triton_context_t *, struct triton_md_handler_t *); void triton_md_unregister_handler(struct triton_md_handler_t *h); int triton_md_enable_handler(struct triton_md_handler_t *h, int mode); int triton_md_disable_handler(struct triton_md_handler_t *h,int mode); -int triton_timer_add(struct triton_ctx_t *ctx, struct triton_timer_t*,int abs_time); +int triton_timer_add(struct triton_context_t *ctx, struct triton_timer_t*,int abs_time); int triton_timer_mod(struct triton_timer_t *,int abs_time); void triton_timer_del(struct triton_timer_t *); diff --git a/accel-pptpd/triton/triton_p.h b/accel-pptpd/triton/triton_p.h index c31efd6e..0aa37b1f 100644 --- a/accel-pptpd/triton/triton_p.h +++ b/accel-pptpd/triton/triton_p.h @@ -3,43 +3,52 @@ #include <pthread.h> #include <sys/epoll.h> +#include <ucontext.h> #include "triton.h" #include "list.h" #include "spinlock.h" +#define CTX_STACK_SIZE 8196 + struct _triton_thread_t { struct list_head entry; struct list_head entry2; pthread_t thread; int terminate:1; - struct _triton_ctx_t *ctx; + struct _triton_context_t *ctx; + ucontext_t uctx; }; -struct _triton_ctx_t +struct _triton_context_t { struct list_head entry; struct list_head entry2; + spinlock_t lock; + struct _triton_thread_t *thread; + struct list_head handlers; struct list_head timers; - - struct _triton_thread_t *thread; struct list_head pending_handlers; struct list_head pending_timers; + + ucontext_t uctx; + int queued:1; + int sleeping:1; int need_close:1; int need_free:1; - struct triton_ctx_t *ud; + struct triton_context_t *ud; }; struct _triton_md_handler_t { struct list_head entry; struct list_head entry2; - struct _triton_ctx_t *ctx; + struct _triton_context_t *ctx; struct epoll_event epoll_event; uint32_t trig_epoll_events; int pending:1; @@ -51,7 +60,7 @@ struct _triton_timer_t struct list_head entry; struct list_head entry2; struct epoll_event epoll_event; - struct _triton_ctx_t *ctx; + struct _triton_context_t *ctx; int fd; int pending:1; struct triton_timer_t *ud; @@ -76,8 +85,8 @@ void md_run(); void md_terminate(); void timer_run(); void timer_terminate(); -struct triton_ctx_t *default_ctx; -int triton_queue_ctx(struct _triton_ctx_t*); +struct triton_context_t *default_ctx; +int triton_queue_ctx(struct _triton_context_t*); void triton_thread_wakeup(struct _triton_thread_t*); int conf_load(const char *fname); void triton_log_error(const char *fmt,...); |