Please someone review this patch. Thanks, Xin
On Thu, Feb 5, 2015 at 2:04 PM, Xin Tong <trent.t...@gmail.com> wrote: > I am planning to implement support for Intel RTM. similar to what is > done for PowerPC. we can default to fault (transaction abort) to the > fallback code path. Would like to check in this test case first. > > > On Thu, Feb 5, 2015 at 1:56 PM, <trent.t...@gmail.com> wrote: >> Add test case for intel restrict transactional memory. compiled with >> Intel ICC 15.0 as well as GCC 4.8. This test case can be used to test >> intel RTM support in the target-i386 frontend. >> >> Signed-off-by: Xin Tong <trent.t...@gmail.com> >> >> diff --git a/tests/tcg/test-intelrtm.c b/tests/tcg/test-intelrtm.c >> new file mode 100644 >> index 0000000..ca1ce16 >> --- /dev/null >> +++ b/tests/tcg/test-intelrtm.c >> @@ -0,0 +1,86 @@ >> +/**************************************************************************** >> +This file contains an example of Intel Restricted Transactional Memory >> (RTM). >> +In the example multiple threads are created to simulatenously increment >> +elements in a shared array. >> + >> +This test case should be compiled with Intel ICC compiler as it uses ICC RTM >> +intrnsics. >> +****************************************************************************/ >> +#include <stdio.h> >> +#include <pthread.h> >> +#include <immintrin.h> /* _XBEGIN_START */ >> + >> +#define ARRAY_SIZE 1024 >> +#define TESTTHREAD_COUNT 32 >> +/* lock for atomic access to the testarray */ >> +static pthread_mutex_t arraylock; >> +static pthread_t *threadarray; >> +static int testarray[ARRAY_SIZE]; >> + >> +static void increment_func(void *arg) >> +{ >> + int i; >> + long int threadnum = (long int)arg; >> + unsigned int status = _xbegin(); >> + if (status == _XBEGIN_STARTED) { >> + /* test _xtest() and _xabort(). fallback path for odd-num thread */ >> + if (_xtest() && (threadnum % 2)) { >> + _xabort(_XABORT_EXPLICIT); >> + } >> + for (i = 0; i < ARRAY_SIZE; ++i) { >> + testarray[i]++; >> + } >> + _xend(); >> + } else { >> + /* fallback path. hold array lock */ >> + pthread_mutex_lock(&arraylock); >> + for (i = 0; i < ARRAY_SIZE; ++i) { >> + testarray[i]++; >> + } >> + /* release array lock */ >> + pthread_mutex_unlock(&arraylock); >> + } >> +} >> + >> +static void run_test(int threadcount) >> +{ >> + int i; >> + /* create the test threads */ >> + for (i = 0; i < threadcount; ++i) { >> + pthread_create(&threadarray[i], NULL, >> + (void *(*)(void *))increment_func, (void*)i); >> + } >> + /* wait for the test threads to finish */ >> + for (i = 0; i < threadcount; ++i) { >> + pthread_join(threadarray[i], NULL); >> + } >> + /* print the end results of the array */ >> + for (i = 0; i < ARRAY_SIZE; ++i) { >> + printf("testarray[%d] is %d\n", i, testarray[i]); >> + } >> +} >> + >> +static void run_setup(int threadcount) >> +{ >> + /* allocate the pthread_t structures */ >> + threadarray = (pthread_t *) malloc(sizeof(pthread_t)*threadcount); >> + /* initialize the arraylock mutex */ >> + if (pthread_mutex_init(&arraylock, NULL) != 0) { >> + printf("arraylock mutex init failed. exiting ...\n"); >> + exit(-1); >> + } >> +} >> + >> +static void run_cleanup(void) >> +{ >> + free(threadarray); >> + pthread_mutex_destroy(&arraylock); >> +} >> + >> +int main(void) >> +{ >> + run_setup(TESTTHREAD_COUNT); >> + run_test(TESTTHREAD_COUNT); >> + run_cleanup(); >> + return 0; >> +}