diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2010-11-21 17:31:00 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2010-11-21 17:31:00 +0300 |
commit | a09fdabf7939819581c6b7797b180a18c4f477fa (patch) | |
tree | 4cfaa02377ff7a660c53099c300de0890dff5d3f /accel-pptpd/triton | |
parent | ddad202eca1c0a1d95321bd396df0dda01620a2b (diff) | |
download | accel-ppp-a09fdabf7939819581c6b7797b180a18c4f477fa.tar.gz accel-ppp-a09fdabf7939819581c6b7797b180a18c4f477fa.zip |
bug fixes
Diffstat (limited to 'accel-pptpd/triton')
-rw-r--r-- | accel-pptpd/triton/md.c | 35 | ||||
-rw-r--r-- | accel-pptpd/triton/mempool.c | 24 | ||||
-rw-r--r-- | accel-pptpd/triton/spinlock.h | 26 | ||||
-rw-r--r-- | accel-pptpd/triton/timer.c | 33 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.c | 26 |
5 files changed, 113 insertions, 31 deletions
diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c index 444aebf0..78330316 100644 --- a/accel-pptpd/triton/md.c +++ b/accel-pptpd/triton/md.c @@ -20,6 +20,10 @@ static void *md_thread(void *arg); static mempool_t *md_pool; +static pthread_mutex_t freed_list_lock = PTHREAD_MUTEX_INITIALIZER; +static LIST_HEAD(freed_list); +static LIST_HEAD(freed_list2); + int md_init(void) { epoll_fd = epoll_create(1); @@ -74,6 +78,8 @@ static void *md_thread(void *arg) for(i = 0; i < n; i++) { h = (struct _triton_md_handler_t *)epoll_events[i].data.ptr; + if (!h->ud) + continue; spin_lock(&h->ctx->lock); if (h->ud) { h->trig_epoll_events |= epoll_events[i].events; @@ -89,6 +95,20 @@ static void *md_thread(void *arg) if (r) triton_thread_wakeup(h->ctx->thread); } + + while (!list_empty(&freed_list2)) { + h = list_entry(freed_list2.next, typeof(*h), entry); + list_del(&h->entry); + mempool_free(h); + } + + pthread_mutex_lock(&freed_list_lock); + while (!list_empty(&freed_list)) { + h = list_entry(freed_list.next, typeof(*h), entry); + list_del(&h->entry); + list_add(&h->entry, &freed_list2); + } + pthread_mutex_unlock(&freed_list_lock); } return NULL; @@ -109,22 +129,27 @@ void __export triton_md_register_handler(struct triton_context_t *ctx, struct tr list_add_tail(&h->entry, &h->ctx->handlers); spin_unlock(&h->ctx->lock); - __sync_fetch_and_add(&triton_stat.md_handler_count, 1); + triton_stat.md_handler_count++; } void __export triton_md_unregister_handler(struct triton_md_handler_t *ud) { struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd; triton_md_disable_handler(ud, MD_MODE_READ | MD_MODE_WRITE); + spin_lock(&h->ctx->lock); + h->ud = NULL; list_del(&h->entry); if (h->pending) list_del(&h->entry2); - h->ud = NULL; spin_unlock(&h->ctx->lock); + sched_yield(); - mempool_free(h); - - __sync_fetch_and_sub(&triton_stat.md_handler_count, 1); + + pthread_mutex_lock(&freed_list_lock); + list_add_tail(&h->entry, &freed_list); + pthread_mutex_unlock(&freed_list_lock); + + triton_stat.md_handler_count--; } int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode) { diff --git a/accel-pptpd/triton/mempool.c b/accel-pptpd/triton/mempool.c index 0ba4ebea..51cde51d 100644 --- a/accel-pptpd/triton/mempool.c +++ b/accel-pptpd/triton/mempool.c @@ -70,7 +70,7 @@ void __export *mempool_alloc(mempool_t *pool) list_del(&it->entry); spin_unlock(&p->lock); - __sync_fetch_and_sub(&triton_stat.mempool_available, size); + triton_stat.mempool_available -= size; it->magic1 = MAGIC1; @@ -88,7 +88,7 @@ void __export *mempool_alloc(mempool_t *pool) it->magic2 = p->magic; *(uint64_t*)(it->data + p->size) = it->magic2; - __sync_fetch_and_add(&triton_stat.mempool_allocated, size); + triton_stat.mempool_allocated += size; return it->ptr; } @@ -110,7 +110,7 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line) it->fname = fname; it->line = line; - __sync_fetch_and_sub(&triton_stat.mempool_available, size); + triton_stat.mempool_available -= size; it->magic1 = MAGIC1; @@ -134,7 +134,7 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line) list_add(&it->entry, &p->ditems); spin_unlock(&p->lock); - __sync_fetch_and_add(&triton_stat.mempool_allocated, size); + triton_stat.mempool_allocated += size; return it->ptr; } @@ -168,10 +168,16 @@ void __export mempool_free(void *ptr) #ifdef MEMDEBUG list_del(&it->entry); #endif +#ifndef MEMPOOL_DISABLE list_add_tail(&it->entry,&it->owner->items); +#endif spin_unlock(&it->owner->lock); - __sync_fetch_and_add(&triton_stat.mempool_available, size); +#ifdef MEMPOOL_DISABLE + _free(it); +#endif + + triton_stat.mempool_available += size; } void __export mempool_clean(mempool_t *pool) @@ -185,8 +191,8 @@ void __export mempool_clean(mempool_t *pool) it = list_entry(p->items.next, typeof(*it), entry); list_del(&it->entry); _free(it); - __sync_fetch_and_sub(&triton_stat.mempool_allocated, size); - __sync_fetch_and_sub(&triton_stat.mempool_available, size); + triton_stat.mempool_allocated -= size; + triton_stat.mempool_available -= size; } spin_unlock(&p->lock); } @@ -220,8 +226,8 @@ void sigclean(int num) it = list_entry(p->items.next, typeof(*it), entry); list_del(&it->entry); _free(it); - __sync_fetch_and_sub(&triton_stat.mempool_allocated, size); - __sync_fetch_and_sub(&triton_stat.mempool_available, size); + triton_stat.mempool_allocated -= size; + triton_stat.mempool_available -= size; } spin_unlock(&p->lock); } diff --git a/accel-pptpd/triton/spinlock.h b/accel-pptpd/triton/spinlock.h index 61f9b016..bb8dcf44 100644 --- a/accel-pptpd/triton/spinlock.h +++ b/accel-pptpd/triton/spinlock.h @@ -1,13 +1,35 @@ #ifndef __TRITON_SPINLOCK_H #define __TRITON_SPINLOCK_H -#ifdef GCC_SPINLOCK -typedef volatile unsigned int spinlock_t; +#if defined(FUTEX_SPINLOCK) + +/*#include <unistd.h> +#include <sys/syscall.h> +#include <linux/futex.h> +typedef volatile int __attribute__((aligned)) spinlock_t; +static inline void _spin_lock(spinlock_t *l) +{ + syscall(SYS_futex, l, FUTEX_WAIT, r, NULL, NULL, 0); +} +static inline void _spin_unlock(spinlock_t *l) +{ + syscall(SYS_futex, l, FUTEX_WAKE, 2, NULL, NULL, 0); +} +#define spin_lock(l) _spin_lock(l) +#define spin_unlock(l) _spin_unlock(l) +#define SPINLOCK_INITIALIZER 1 +#define spinlock_init(l) {*(l)=1;}*/ + +#elif defined(GCC_SPINLOCK) + +typedef volatile int __attribute__((aligned)) spinlock_t; #define spin_lock(l) {while(__sync_lock_test_and_set(l,1));} #define spin_unlock(l) __sync_lock_release(l) #define SPINLOCK_INITIALIZER 0 #define spinlock_init(l) {*(l)=0;} + #else + #include <pthread.h> typedef pthread_mutex_t spinlock_t; #define spin_lock(l) pthread_mutex_lock(l) diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c index 43cb56f6..95a540a6 100644 --- a/accel-pptpd/triton/timer.c +++ b/accel-pptpd/triton/timer.c @@ -26,6 +26,10 @@ static void *timer_thread(void *arg); static mempool_t *timer_pool; +static pthread_mutex_t freed_list_lock = PTHREAD_MUTEX_INITIALIZER; +static LIST_HEAD(freed_list); +static LIST_HEAD(freed_list2); + int timer_init(void) { epoll_fd = epoll_create(1); @@ -81,6 +85,8 @@ void *timer_thread(void *arg) for(i = 0; i < n; i++) { t = (struct _triton_timer_t *)epoll_events[i].data.ptr; + if (!t->ud) + continue; spin_lock(&t->ctx->lock); if (t->ud) { if (!t->pending) { @@ -95,6 +101,20 @@ void *timer_thread(void *arg) if (r) triton_thread_wakeup(t->ctx->thread); } + + while (!list_empty(&freed_list2)) { + t = list_entry(freed_list2.next, typeof(*t), entry); + list_del(&t->entry); + mempool_free(t); + } + + pthread_mutex_lock(&freed_list_lock); + while (!list_empty(&freed_list)) { + t = list_entry(freed_list.next, typeof(*t), entry); + list_del(&t->entry); + list_add(&t->entry, &freed_list2); + } + pthread_mutex_unlock(&freed_list_lock); } return NULL; @@ -143,7 +163,7 @@ int __export triton_timer_add(struct triton_context_t *ctx, struct triton_timer_ goto out_err; } - __sync_fetch_and_add(&triton_stat.timer_count, 1); + triton_stat.timer_count++; return 0; @@ -179,15 +199,20 @@ void __export triton_timer_del(struct triton_timer_t *ud) epoll_ctl(epoll_fd, EPOLL_CTL_DEL, t->fd, &t->epoll_event); close(t->fd); spin_lock(&t->ctx->lock); + t->ud = NULL; list_del(&t->entry); if (t->pending) list_del(&t->entry2); - t->ud = NULL; spin_unlock(&t->ctx->lock); + sched_yield(); - mempool_free(t); + + pthread_mutex_lock(&freed_list_lock); + list_add_tail(&t->entry, &freed_list); + pthread_mutex_unlock(&freed_list_lock); + ud->tpd = NULL; - __sync_fetch_and_sub(&triton_stat.timer_count, 1); + triton_stat.timer_count--; } diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index e7855ccf..34c526e0 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -60,7 +60,7 @@ static void* triton_thread(struct _triton_thread_t *thread) thread->ctx->thread = thread; thread->ctx->queued = 0; spin_unlock(&thread->ctx->lock); - __sync_fetch_and_sub(&triton_stat.context_pending, 1); + triton_stat.context_pending--; } else { //printf("thread: %p: sleeping\n", thread); if (!terminate) @@ -69,11 +69,11 @@ static void* triton_thread(struct _triton_thread_t *thread) if (terminate) return NULL; - __sync_fetch_and_sub(&triton_stat.thread_active, 1); + triton_stat.thread_active--; //printf("thread %p: enter sigwait\n", thread); sigwait(&set, &sig); //printf("thread %p: exit sigwait\n", thread); - __sync_fetch_and_add(&triton_stat.thread_active, 1); + triton_stat.thread_active++; if (!thread->ctx) continue; @@ -106,6 +106,8 @@ cont: if (thread->ctx->need_free) { //printf("- context %p removed\n", thread->ctx); + spin_lock(&thread->ctx->lock); + spin_unlock(&thread->ctx->lock); mempool_free(thread->ctx->uctx.uc_stack.ss_sp); mempool_free(thread->ctx); } @@ -148,10 +150,12 @@ static void ctx_thread(struct _triton_context_t *ctx) 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->ud->read(h->ud)) + continue; if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) if (h->ud && h->ud->write) - h->ud->write(h->ud); + if (h->ud->write(h->ud)) + continue; h->trig_epoll_events = 0; continue; } @@ -212,7 +216,7 @@ int triton_queue_ctx(struct _triton_context_t *ctx) spin_unlock(&threads_lock); ctx->queued = 1; //printf("ctx %p: queued\n", ctx); - __sync_fetch_and_add(&triton_stat.context_pending, 1); + triton_stat.context_pending++; return 0; } @@ -265,8 +269,8 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg) list_add_tail(&ctx->entry, &ctx_list); spin_unlock(&ctx_list_lock); - __sync_fetch_and_add(&triton_stat.context_sleeping, 1); - __sync_fetch_and_add(&triton_stat.context_count, 1); + triton_stat.context_sleeping++; + triton_stat.context_count++; return 0; } @@ -313,7 +317,7 @@ void __export triton_context_unregister(struct triton_context_t *ud) terminate = 1; spin_unlock(&ctx_list_lock); - __sync_fetch_and_sub(&triton_stat.context_count, 1); + triton_stat.context_count--; if (terminate) { list_for_each_entry(t, &threads, entry) @@ -343,7 +347,7 @@ void __export triton_context_schedule(struct triton_context_t *ud) ctx->thread = NULL; spin_unlock(&ctx->lock); - __sync_fetch_and_add(&triton_stat.context_sleeping, 1); + triton_stat.context_sleeping++; if (swapcontext(&ctx->uctx, uctx)) triton_log_error("swaswpntext: %s\n", strerror(errno)); @@ -375,7 +379,7 @@ int __export triton_context_wakeup(struct triton_context_t *ud) if (r) triton_thread_wakeup(ctx->thread); - __sync_fetch_and_sub(&triton_stat.context_sleeping, 1); + triton_stat.context_sleeping--; return 0; } |