/************************************** * file : synchtest2.c ************************************** * * FILE: synchtest2.c * * DESCRIPTION: netapi user space transport * library test application - more synchtest * * REVISION HISTORY: rev 0.0.1 * * Copyright (c) Texas Instruments Incorporated 2010-2011 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ #include #include #include #include #include #include #include #include #include "netsync.h" #include "netapi_util.h" //#define INC_TO 1000000 // one million. #define INC_TO 10000 // one million... NETAPI_ATOMIC64_T global_int=NETAPI_ATOMIC_INIT64(0LL) ; __thread blah=0; int blah2=0; NETAPI_SPINLOCK_T spin_test; pid_t gettid( void ) { return syscall( __NR_gettid ); } void *thread_routine( void *arg ) { int i; int proc_num = (int)(long)arg; cpu_set_t set; int v1, v2,v3; #if 0 CPU_ZERO( &set ); CPU_SET( proc_num, &set ); if (sched_setaffinity( gettid(), sizeof( cpu_set_t ), &set )) { perror( "sched_setaffinity" ); return NULL; } #endif for (i = 0; i < INC_TO; i++) { v1 = netapi_timing_start(); netapi_atomic_add64(&global_int,1LL); v1= netapi_timing_stop() - v1; sched_yield(); v2 = netapi_timing_start(); blah+=1; v2= netapi_timing_stop() - v2; v3 = netapi_timing_start(); blah2+=1; v3= netapi_timing_stop() - v3; if(i<10) { printf("thread %d -> a64 costs %d, tls costs %d simple++ costs %d\n", proc_num,v1,v2,v3);} sched_yield(); } printf("thead %d -> blah=%d\n",proc_num, blah); printf("now try spin lock test. i'm thread %d, about to grab lock \n", proc_num); //now we try the synch_lock_and_test v1 = netapi_timing_start(); netapi_spinlock_lock(&spin_test); v2 = netapi_timing_stop(); printf("i'm thread %d. I've locked it, val= %d, it took cycles=%d to get it\ngoing to sleep..",proc_num,spin_test,v2-v1); sleep(1); printf(" i'm back. i'm thread %d. i'm unlocking now\n",proc_num); netapi_spinlock_unlock(&spin_test); return NULL; } int main() { int procs = 0; int i; pthread_t *thrs; printf("at start up\n"); // Getting number of CPUs procs = (int)sysconf( _SC_NPROCESSORS_ONLN ); if (procs < 0) { perror( "sysconf" ); return -1; } printf(" num cpus = %d\n",procs); if (procs==1) {procs+=1; printf("adding 2nd 'core' \n");} thrs = malloc( sizeof( pthread_t ) * procs ); if (thrs == NULL) { perror( "malloc" ); return -1; } //initialize spinlock netapi_spinlock_init(&spin_test); printf( "Starting %d threads...\n", procs ); for (i = 0; i < procs; i++) { if (pthread_create( &thrs[i], NULL, thread_routine, (void *)(long)i )) { perror( "pthread_create" ); procs = i; break; } } for (i = 0; i < procs; i++) pthread_join( thrs[i], NULL ); free( thrs ); printf( "global_int value is: %lld bare global_int is %d\n", global_int.val, blah2 ); printf( "Expected value is: %d\n", INC_TO * procs ); return 0; }