mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
optimize fiber_mutex by using context switch when the owner and waiter are in the same thread
This commit is contained in:
parent
f5d6b15f33
commit
1f2f79c192
@ -9,7 +9,8 @@ extern "C" {
|
||||
|
||||
typedef struct ACL_FIBER_MUTEX ACL_FIBER_MUTEX;
|
||||
|
||||
#define FIBER_MUTEX_F_LOCK_TRY (1 << 0)
|
||||
#define FIBER_MUTEX_F_LOCK_TRY (1 << 0)
|
||||
#define FIBER_MUTEX_F_SWITCH_FIRST (1 << 1)
|
||||
|
||||
FIBER_API ACL_FIBER_MUTEX *acl_fiber_mutex_create(unsigned flag);
|
||||
FIBER_API void acl_fiber_mutex_free(ACL_FIBER_MUTEX *mutex);
|
||||
|
@ -488,6 +488,15 @@ static int peek_more(EVENT_URING *ep)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -ETIME) {
|
||||
printf("%s(%d): ETIME\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (ret == -ECANCELED) {
|
||||
printf("%s(%d): ECANCELED\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (ctx == NULL) {
|
||||
printf("%s(%d): ctx NULL\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (ret == -ETIME || ret == -ECANCELED || ctx == NULL) {
|
||||
continue;
|
||||
}
|
||||
@ -555,6 +564,15 @@ AGAIN:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -ETIME) {
|
||||
printf("%s(%d): ETIME\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (ret == -ECANCELED) {
|
||||
printf("%s(%d): ECANCELED\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (ctx == NULL) {
|
||||
printf("%s(%d): ctx NULL\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
if (ret == -ETIME || ret == -ECANCELED || ctx == NULL) {
|
||||
return 1;
|
||||
}
|
||||
@ -631,8 +649,8 @@ EVENT *event_io_uring_create(int size)
|
||||
__FUNCTION__, __LINE__, strerror(-ret), eu->sqe_size);
|
||||
abort();
|
||||
} else {
|
||||
printf("%s(%d): init io_uring ok, size=%zd\r\n",
|
||||
__FUNCTION__, __LINE__, eu->sqe_size);
|
||||
printf("%s(%d): thread-%lu init io_uring ok, size=%zd\r\n",
|
||||
__FUNCTION__, __LINE__, pthread_self(), eu->sqe_size);
|
||||
}
|
||||
|
||||
if (!(params.features & IORING_FEAT_FAST_POLL)) {
|
||||
|
@ -713,6 +713,7 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *),
|
||||
head = ring_pop_head(&__thread_fiber->dead);
|
||||
if (head == NULL) {
|
||||
fiber = __fiber_alloc_fn(fiber_start, attr);
|
||||
fiber->tid = pthread_self();
|
||||
} else {
|
||||
fiber = APPL(head, ACL_FIBER, me);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ struct SYNC_WAITER;
|
||||
|
||||
struct ACL_FIBER {
|
||||
FIBER_BASE *base;
|
||||
pthread_t tid;
|
||||
fiber_status_t status;
|
||||
RING me;
|
||||
unsigned id;
|
||||
|
@ -57,7 +57,6 @@ static int fiber_mutex_lock_once(ACL_FIBER_MUTEX *mutex)
|
||||
if (pthread_mutex_trylock(&mutex->thread_lock) == 0) {
|
||||
array_delete(mutex->waiters, pos, NULL);
|
||||
pthread_mutex_unlock(&mutex->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -147,7 +146,13 @@ int acl_fiber_mutex_unlock(ACL_FIBER_MUTEX *mutex)
|
||||
}
|
||||
|
||||
if (fiber) {
|
||||
sync_waiter_wakeup(fiber->sync, fiber);
|
||||
if (!(mutex->flags & FIBER_MUTEX_F_SWITCH_FIRST)) {
|
||||
sync_waiter_wakeup(fiber->sync, fiber);
|
||||
} else if (pthread_self() == fiber->tid) {
|
||||
acl_fiber_ready(fiber);
|
||||
} else {
|
||||
sync_waiter_wakeup(fiber->sync, fiber);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../stamp.h"
|
||||
|
||||
static int __fibers_count = 10;
|
||||
static int __event_type = FIBER_EVENT_KERNEL;
|
||||
|
||||
static void fiber_main(ACL_FIBER *fiber, void *ctx)
|
||||
{
|
||||
@ -36,13 +37,12 @@ static void test1(void)
|
||||
acl_fiber_create(fiber_main, l, 320000);
|
||||
}
|
||||
|
||||
acl_fiber_schedule();
|
||||
acl_fiber_schedule_with(__event_type);
|
||||
acl_fiber_mutex_free(l);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int __event_type = FIBER_EVENT_KERNEL;
|
||||
static int __use_yield = 0;
|
||||
static int __use_event = 0;
|
||||
static ACL_FIBER_MUTEX **__locks;
|
||||
@ -58,6 +58,8 @@ static void fiber_main2(ACL_FIBER *fiber acl_unused, void *ctx acl_unused)
|
||||
int i, ret;
|
||||
ACL_FIBER_MUTEX *l;
|
||||
|
||||
printf("thread-%lu, fiber-%d start!\r\n", (long) pthread_self(), acl_fiber_self());
|
||||
|
||||
for (i = 0; i < __nloop; i++) {
|
||||
l = __locks[i % __nlocks];
|
||||
ret = acl_fiber_mutex_lock(l);
|
||||
@ -66,7 +68,11 @@ static void fiber_main2(ACL_FIBER *fiber acl_unused, void *ctx acl_unused)
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
//acl_fiber_delay(100);
|
||||
|
||||
ret = acl_fiber_mutex_unlock(l);
|
||||
|
||||
//printf(">>fiber-%d unlock\n", acl_fiber_self());
|
||||
if (ret) {
|
||||
printf("%s: unlock error=%s\r\n", __FUNCTION__, strerror(ret));
|
||||
assert(ret == 0);
|
||||
@ -77,12 +83,14 @@ static void fiber_main2(ACL_FIBER *fiber acl_unused, void *ctx acl_unused)
|
||||
acl_fiber_yield();
|
||||
}
|
||||
__count++;
|
||||
|
||||
//acl_fiber_delay(100);
|
||||
}
|
||||
|
||||
if (--__nfibers == 0) {
|
||||
printf("thread-%lu, all fibers over, count=%d!\r\n",
|
||||
(unsigned long) pthread_self(), __count);
|
||||
acl_fiber_schedule_stop();
|
||||
printf("%s: thread-%lu, all fibers over, count=%d!\r\n",
|
||||
__FUNCTION__, (unsigned long) pthread_self(), __count);
|
||||
//acl_fiber_schedule_stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,8 +111,8 @@ static void fiber_main3(ACL_FIBER *fiber acl_unused, void *ctx acl_unused)
|
||||
}
|
||||
|
||||
if (--__nfibers == 0) {
|
||||
printf("thread-%lu, all fibers over, count=%d\r\n",
|
||||
(unsigned long) pthread_self(), __count);
|
||||
printf("%s: thread-%lu, all fibers over, count=%d\r\n",
|
||||
__FUNCTION__, (unsigned long) pthread_self(), __count);
|
||||
//acl_fiber_schedule_stop();
|
||||
}
|
||||
}
|
||||
@ -168,10 +176,12 @@ static void test2(int nthreads, int nthreads2, unsigned flags)
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
pthread_create(&threads[i], NULL, thread_main, NULL);
|
||||
printf("--create fibers thread-%lu\r\n", (long) threads[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < nthreads2; i++) {
|
||||
pthread_create(&threads2[i], NULL, thread_alone_main, NULL);
|
||||
printf("--create alone thread-%lu\r\n", (long) threads2[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
@ -214,18 +224,50 @@ static void usage(const char *procname)
|
||||
" -E [if use fiber_event]\r\n"
|
||||
" -Y [if yield after unlock]\r\n"
|
||||
" -T [if use first try lock for mutex]\r\n"
|
||||
" -S [if using fiber switching first when they're in the same thread]\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
static void test_lock(void)
|
||||
{
|
||||
int i;
|
||||
pthread_mutex_t lock;
|
||||
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
int ret = pthread_mutex_trylock(&lock);
|
||||
if (ret != 0) {
|
||||
printf("lock error %s, i=%d\n", strerror(ret), i);
|
||||
exit(1);
|
||||
}
|
||||
printf("lock ok, i=%d\n", i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
int ret = pthread_mutex_lock(&lock);
|
||||
if (ret != 0) {
|
||||
printf("unlock error, i=%d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
printf("unlock ok, i=%d\n", i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ch, nthreads = 2, nthreads2 = 0;
|
||||
unsigned flags = 0;
|
||||
char action[64];
|
||||
|
||||
snprintf(action, sizeof(action), "test1");
|
||||
if (0) {
|
||||
test_lock();
|
||||
}
|
||||
|
||||
while ((ch = getopt(argc, argv, "he:a:t:c:p:n:l:EYT")) > 0) {
|
||||
snprintf(action, sizeof(action), "test2");
|
||||
|
||||
while ((ch = getopt(argc, argv, "he:a:t:c:p:n:l:EYTS")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
@ -266,6 +308,9 @@ int main(int argc, char *argv[])
|
||||
case 'T':
|
||||
flags |= FIBER_MUTEX_F_LOCK_TRY;
|
||||
break;
|
||||
case 'S':
|
||||
flags |= FIBER_MUTEX_F_SWITCH_FIRST;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user