From d8f3bcd4ec0e2dc222209c6b05060892f65f4a67 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Wed, 26 Apr 2023 14:11:40 +0800 Subject: [PATCH] test fiber in sharing stack mode. --- lib_fiber/c/Makefile | 1 + lib_fiber/c/src/fiber/fiber_unix.c | 15 +++++++--- lib_fiber/samples/client2/main.c | 14 ++++++++-- lib_fiber/samples/redis/main.cpp | 45 ++++++++++++++++++++++-------- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/lib_fiber/c/Makefile b/lib_fiber/c/Makefile index b7b7a7367..d9ffcaefb 100644 --- a/lib_fiber/c/Makefile +++ b/lib_fiber/c/Makefile @@ -10,6 +10,7 @@ RANLIB = ${ENV_RANLIB} #JMP_CTX = USE_CONTEXT JMP_CTX = USE_JMP_DEF #JMP_CTX = USE_BOOST_JMP +#JMP_CTX = USE_JMP_SYS CFLAGS = -c -g -W \ -std=gnu99 \ diff --git a/lib_fiber/c/src/fiber/fiber_unix.c b/lib_fiber/c/src/fiber/fiber_unix.c index da30d241c..b41885193 100644 --- a/lib_fiber/c/src/fiber/fiber_unix.c +++ b/lib_fiber/c/src/fiber/fiber_unix.c @@ -20,7 +20,8 @@ #elif defined(USE_JMP_EXP) # define USE_JMP # include "exp_jmp.h" -#else +#elif defined(USE_JMP_SYS) +# define USE_JMP # define SETJMP(ctx) sigsetjmp(ctx, 0) # define LONGJMP(ctx) siglongjmp(ctx, 1) #endif // USE_BOOST_JMP @@ -42,11 +43,9 @@ typedef struct FIBER_UNIX { void *arg; #else # if defined(USE_JMP_DEF) -# if defined(__x86_64__) unsigned long long env[10]; -# else +# elif defined(USE_JMP_SYS) sigjmp_buf env; -# endif # elif defined(USE_JMP_EXP) label_t env; # endif @@ -199,13 +198,21 @@ void fiber_real_swap(ACL_FIBER *from, ACL_FIBER *to) /* Use setcontext() for the initial jump, as it allows us to set up * a stack, but continue with longjmp() as it's much faster. */ +# if defined(USE_JMP_SYS) + if (SETJMP(((FIBER_UNIX*) from)->env) == 0) { +# else if (SETJMP(&((FIBER_UNIX*) from)->env) == 0) { +# endif /* If the fiber was ready for the first time, just call the * setcontext() for the fiber to start, else just jump to the * fiber's running stack. */ if (to->flag & FIBER_F_STARTED) { +# if defined(USE_JMP_SYS) + LONGJMP(((FIBER_UNIX*) to)->env); +#else LONGJMP(&((FIBER_UNIX*) to)->env); +#endif } else { setcontext(((FIBER_UNIX*) to)->context); } diff --git a/lib_fiber/samples/client2/main.c b/lib_fiber/samples/client2/main.c index cedaf79db..01dcb9281 100644 --- a/lib_fiber/samples/client2/main.c +++ b/lib_fiber/samples/client2/main.c @@ -40,6 +40,7 @@ static int __max_fibers = 100; static int __left_fibers = 100; static int __read_data = 1; static int __stack_size = 32000; +static int __stack_share = 0; static struct timeval __begin; static int check_write(SOCKET fd, int timeout) @@ -221,11 +222,16 @@ static void fiber_connect(ACL_FIBER *fiber acl_unused, void *ctx acl_unused) static void fiber_main(ACL_FIBER *fiber acl_unused, void *ctx acl_unused) { int i; + ACL_FIBER_ATTR attr; + + acl_fiber_attr_init(&attr); + acl_fiber_attr_setstacksize(&attr, __stack_size); + acl_fiber_attr_setsharestack(&attr, __stack_share ? 1 : 0); sleep(1); // just waiting for the IO event fiber to run first for (i = 0; i < __max_fibers; i++) { - acl_fiber_create(fiber_connect, NULL, __stack_size); + acl_fiber_create2(&attr, fiber_connect, NULL); } } @@ -239,6 +245,7 @@ static void usage(const char *procname) " -r io_timeout\r\n" " -c max_fibers\r\n" " -S [if using single IO, dafault: no]\r\n" + " -Z [if sharing fiber stack, default: no]\r\n" " -d fiber_delay_ms\r\n" " -z stack_size\r\n" " -n max_loop\r\n" @@ -272,7 +279,7 @@ int main(int argc, char *argv[]) snprintf(__server_ip, sizeof(__server_ip), "%s", "127.0.0.1"); - while ((ch = getopt(argc, argv, "hc:n:s:p:t:r:Sd:z:e:m:")) > 0) { + while ((ch = getopt(argc, argv, "hc:n:s:p:t:r:Sd:z:e:m:Z")) > 0) { switch (ch) { case 'h': usage(argv[0]); @@ -319,6 +326,9 @@ int main(int argc, char *argv[]) event_mode = FIBER_EVENT_IO_URING; } break; + case 'Z': + __stack_share = 1; + break; default: break; } diff --git a/lib_fiber/samples/redis/main.cpp b/lib_fiber/samples/redis/main.cpp index e64dc8a1a..7b9dbd0fd 100644 --- a/lib_fiber/samples/redis/main.cpp +++ b/lib_fiber/samples/redis/main.cpp @@ -7,6 +7,8 @@ static int __oper_count = 100; static struct timeval __begin; static struct timeval __finish; +acl::string addr("127.0.0.1:6379"), passwd; + //#define USE_PIPELINE static void fiber_redis(ACL_FIBER *fiber, void *ctx) @@ -15,9 +17,13 @@ static void fiber_redis(ACL_FIBER *fiber, void *ctx) acl::redis_client_pipeline* pipeline = (acl::redis_client_pipeline*) ctx; acl::redis cmd; cmd.set_pipeline(pipeline); -#else +#elif 1 acl::redis_client_cluster *cluster = (acl::redis_client_cluster *) ctx; acl::redis cmd(cluster); +#else + (void) ctx; + acl::redis_client conn(addr, 0, 0); + acl::redis cmd(&conn); #endif acl::string key, val; @@ -102,15 +108,17 @@ static void usage(const char *procname) " -n operation_count\r\n" " -c fibers count\r\n" " -t conn_timeout\r\n" - " -r rw_timeout\r\n", procname); + " -r rw_timeout\r\n" + " -S [if use sharing stack]\r\n" + , procname); } int main(int argc, char *argv[]) { int ch, i, conn_timeout = 2, rw_timeout = 2; - acl::string addr("127.0.0.1:6379"), passwd; + bool share_stack = false; - while ((ch = getopt(argc, argv, "hs:n:c:r:t:p:")) > 0) { + while ((ch = getopt(argc, argv, "hs:n:c:r:t:p:S")) > 0) { switch (ch) { case 'h': usage(argv[0]); @@ -134,6 +142,9 @@ int main(int argc, char *argv[]) case 'p': passwd = optarg; break; + case 'S': + share_stack = true; + break; default: break; } @@ -144,26 +155,36 @@ int main(int argc, char *argv[]) acl_fiber_msg_stdout_enable(1); #ifdef USE_PIPELINE - acl::redis_client_pipeline pipeline(addr.c_str(), conn_timeout, - rw_timeout); - pipeline.start(); + acl::redis_client_pipeline* pipeline = + new acl::redis_client_pipeline((addr.c_str(), conn_timeout, + rw_timeout); + pipeline->start(); #else - acl::redis_client_cluster cluster; - cluster.set_password("default", passwd); - cluster.set(addr.c_str(), 0, conn_timeout, rw_timeout); + acl::redis_client_cluster* cluster = new acl::redis_client_cluster; + cluster->set_password("default", passwd); + cluster->set(addr.c_str(), 0, conn_timeout, rw_timeout); #endif gettimeofday(&__begin, NULL); + ACL_FIBER_ATTR attr; + acl_fiber_attr_init(&attr); + + acl_fiber_attr_setstacksize(&attr, 128000); + acl_fiber_attr_setsharestack(&attr, share_stack ? 1 : 0); + for (i = 0; i < __fibers_count; i++) { #ifdef USE_PIPELINE - acl_fiber_create(fiber_redis, &pipeline, 327680); + acl_fiber_create2(&attr, fiber_redis, pipeline); #else - acl_fiber_create(fiber_redis, &cluster, 327680); + acl_fiber_create2(&attr, fiber_redis, cluster); #endif } acl_fiber_schedule(); + printf("Enter any key to exit ..."); + fflush(stdout); + getchar(); return 0; }