Skip to content

Instantly share code, notes, and snippets.

@haileys
Created December 29, 2013 11:25
Show Gist options
  • Save haileys/8169449 to your computer and use it in GitHub Desktop.
Save haileys/8169449 to your computer and use it in GitHub Desktop.
Thread #0 was switched to 125044 times
Thread #1 was switched to 124994 times
Thread #2 was switched to 124994 times
Thread #3 was switched to 124993 times
Thread #4 was switched to 124993 times
Thread #5 was switched to 124994 times
Thread #6 was switched to 124994 times
Thread #7 was switched to 124993 times
1,000,000 thread switches took 2.143874 seconds
466445 thread switches per second
#include <luajit-2.0/lauxlib.h>
#include <luajit-2.0/lualib.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#define countof(xs) (sizeof(xs) / sizeof(*(xs)))
pthread_mutex_t gil = PTHREAD_MUTEX_INITIALIZER;
size_t ctx_switches = 0;
struct timeval started_at;
struct thread_ctx {
pthread_t th;
lua_State* lua;
int i;
size_t switches;
} threads[8];
void gil_lock()
{
pthread_mutex_lock(&gil);
}
void gil_unlock()
{
pthread_mutex_unlock(&gil);
}
void done()
{
for(size_t i = 0; i < countof(threads); i++) {
printf("Thread #%zu was switched to %7zu times\n", i, threads[i].switches);
}
printf("\n");
struct timeval ended_at;
gettimeofday(&ended_at, NULL);
double elapsed = ended_at.tv_sec - started_at.tv_sec;
elapsed += (ended_at.tv_usec - started_at.tv_usec) / 1000000.0;
printf("1,000,000 thread switches took %lf seconds\n", elapsed);
printf("%d thread switches per second\n", (int)(1000000.0 / elapsed));
exit(0);
}
int yield(lua_State* l)
{
if(++ctx_switches == 1000000) {
done();
}
struct thread_ctx* th = lua_touserdata(l, 1);
th->switches++;
gil_unlock();
gil_lock();
return 0;
}
void* thread_main(void* ctx_)
{
struct thread_ctx* ctx = ctx_;
gil_lock();
lua_getglobal(ctx->lua, "thread_main");
lua_pushlightuserdata(ctx->lua, ctx);
lua_call(ctx->lua, 1, 0);
return NULL;
}
int main()
{
gettimeofday(&started_at, NULL);
lua_State* l = lua_open();
luaL_openlibs(l);
luaL_dostring(l,
"function thread_main(th)\n"
" while true do\n"
" yield(th)\n"
" end\n"
"end\n"
);
lua_pushcfunction(l, yield);
lua_setglobal(l, "yield");
for(size_t i = 0; i < countof(threads); i++) {
threads[i].i = i;
threads[i].lua = lua_newthread(l);
pthread_create(&threads[i].th, NULL, thread_main, &threads[i]);
}
for(size_t i = 0; i < countof(threads); i++) {
void* val;
pthread_join(threads[i].th, &val);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment