From 4feeab8c61334ec73172fa01cda951dafde2505f Mon Sep 17 00:00:00 2001 From: blacksirius Date: Sun, 3 Jun 2012 18:53:02 +0000 Subject: feature merge bs-coreoptimize->trunk: Atomic Operations, Threading, Spinlock implemnetation. [commit 1/2, windows will followup] - Added Abstractions for Atomic Operations (lock instructions.. windows guy's may now this as Interlocked* stuff ..) - Added Threading api abstraction for Pthread based OS's and Windows - Added Spinlock Implementation (uses CAS / if you need more informations - just read the source - its simple.) - Due to Interlocked(Compare)Exchange64 .. we now require at least i686 (Pentium Pro) for 32Bit Builds :) youll also may feel some performance improvements when using 32bit builsd due to "newer" minimal arch the compiler is now able to use CMOV's .... ================================================================ = Important Warning: ================================================================ Dont use threading at the moment athena is not threadsafe! you'll mess up everthing when accessing data from other threads .., no synchronization is provided. A way to process tasks asynchronously will come up after / with the new socket system. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16221 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/test/Makefile.in | 61 ++++++++++++++++++++++++ src/test/test_spinlock.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 src/test/Makefile.in create mode 100644 src/test/test_spinlock.c (limited to 'src/test') diff --git a/src/test/Makefile.in b/src/test/Makefile.in new file mode 100644 index 000000000..c601de9cb --- /dev/null +++ b/src/test/Makefile.in @@ -0,0 +1,61 @@ + +COMMON_H = $(shell ls ../common/*.h) + +MT19937AR_OBJ = ../../3rdparty/mt19937ar/mt19937ar.o +MT19937AR_H = ../../3rdparty/mt19937ar/mt19937ar.h +MT19937AR_INCLUDE = -I../../3rdparty/mt19937ar + +LIBCONFIG_OBJ = ../../3rdparty/libconfig/libconfig.o ../../3rdparty/libconfig/grammar.o \ + ../../3rdparty/libconfig/scanctx.o ../../3rdparty/libconfig/scanner.o ../../3rdparty/libconfig/strbuf.o +LIBCONFIG_H = ../../3rdparty/libconfig/libconfig.h ../../3rdparty/libconfig/grammar.h \ + ../../3rdparty/libconfig/parsectx.h ../../3rdparty/libconfig/scanctx.h ../../3rdparty/libconfig/scanner.h \ + ../../3rdparty/libconfig/strbuf.h ../../3rdparty/libconfig/wincompat.h +LIBCONFIG_INCLUDE = -I../../3rdparty/libconfig + +TEST_SPINLOCK_OBJ=obj/test_spinlock.o +TEST_SPINLOCK_H= +TEST_SPINLOCK_DEPENDS=obj $(TEST_SPINLOCK_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) + +@SET_MAKE@ + +##################################################################### +.PHONY :all test_spinlock + +all: test_spinlock + +clean: + @echo " CLEAN test" + @rm -rf *.o obj ../../test_spinlock@EXEEXT@ + +##################################################################### + +# object directories + +obj: + @echo " MKDIR obj" + @-mkdir obj + +#executables + +test_spinlock: $(TEST_SPINLOCK_DEPENDS) + @echo " LD $@" + @@CC@ @LDFLAGS@ -o ../../test_spinlock@EXEEXT@ $(TEST_SPINLOCK_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ + +# login object files + +obj/%.o: %.c $(COMMON_H) $(MT19937AR_H) $(LIBCONFIG_H) + @echo " CC $<" + @@CC@ @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< + +# missing object files +../common/obj_all/common.a: + @$(MAKE) -C ../common sql + +../common/obj_sql/common_sql.a: + @$(MAKE) -C ../common sql + +MT19937AR_OBJ: + @$(MAKE) -C ../../3rdparty/mt19937ar + +LIBCONFIG_OBJ: + @$(MAKE) -C ../../3rdparty/libconfig diff --git a/src/test/test_spinlock.c b/src/test/test_spinlock.c new file mode 100644 index 000000000..878ee8bab --- /dev/null +++ b/src/test/test_spinlock.c @@ -0,0 +1,117 @@ + +#include "../common/core.h" +#include "../common/atomic.h" +#include "../common/thread.h" +#include "../common/spinlock.h" +#include "../common/showmsg.h" + +#include +#include + +// +// Simple test for the spinlock implementation to see if it works properly.. +// + + + +#define THRC 32 //thread Count +#define PERINC 100000 +#define LOOPS 47 + + +static SPIN_LOCK lock; +static int val = 0; +static volatile int32 done_threads = 0; + +static void *worker(void *p){ + register int i; + + for(i = 0; i < PERINC; i++){ + EnterSpinLock(&lock); + EnterSpinLock(&lock); + + val++; + + LeaveSpinLock(&lock); + LeaveSpinLock(&lock); + } + + InterlockedIncrement(&done_threads); + + return NULL; +}//end: worker() + + +int do_init(int argc, char **argv){ + rAthread t[THRC]; + int j, i; + int ok; + + ShowStatus("==========\n"); + ShowStatus("TEST: %u Runs, (%u Threads)\n", LOOPS, THRC); + ShowStatus("This can take a while\n"); + ShowStatus("\n\n"); + + ok =0; + for(j = 0; j < LOOPS; j++){ + val = 0; + done_threads = 0; + + InitializeSpinLock(&lock); + + + for(i =0; i < THRC; i++){ + t[i] = rathread_createEx( worker, NULL, 1024*512, RAT_PRIO_NORMAL); + } + + + while(1){ + if(InterlockedCompareExchange(&done_threads, THRC, THRC) == THRC) + break; + + rathread_yield(); + } + + FinalizeSpinLock(&lock); + + // Everything fine? + if(val != (THRC*PERINC) ){ + printf("FAILED! (Result: %u, Expected: %u)\n", val, (THRC*PERINC) ); + }else{ + printf("OK! (Result: %u, Expected: %u)\n", val, (THRC*PERINC) ); + ok++; + } + + } + + + if(ok != LOOPS){ + ShowFatalError("Test failed.\n"); + exit(1); + }else{ + ShowStatus("Test passed.\n"); + exit(0); + } + + +return 0; +}//end: do_init() + + +void do_abort(){ +}//end: do_abort() + + +void set_server_type(){ + SERVER_TYPE = ATHENA_SERVER_NONE; +}//end: set_server_type() + + +void do_final(){ +}//end: do_final() + + +int parse_console(const char* command){ + return 0; +}//end: parse_console + -- cgit v1.2.3-60-g2f50