1 /**************************************
2 * file : synchtest2.c
3 **************************************
4 * * FILE: synchtest2.c
5 *
6 * DESCRIPTION: netapi user space transport
7 * library test application - more synchtest
8 *
9 * REVISION HISTORY: rev 0.0.1
10 *
11 * Copyright (c) Texas Instruments Incorporated 2010-2011
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the
23 * distribution.
24 *
25 * Neither the name of Texas Instruments Incorporated nor the names of
26 * its contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 ******************************************************************************/
42 #include <stdio.h>
43 #include <pthread.h>
44 #include <unistd.h>
45 #include <stdlib.h>
46 #include <sched.h>
47 #include <linux/unistd.h>
48 #include <sys/syscall.h>
49 #include <errno.h>
51 #include "netsync.h"
52 #include "netapi_util.h"
53 //#define INC_TO 1000000 // one million.
54 #define INC_TO 10000 // one million...
56 NETAPI_ATOMIC64_T global_int=NETAPI_ATOMIC_INIT64(0LL) ;
57 __thread blah=0;
58 int blah2=0;
59 NETAPI_SPINLOCK_T spin_test;
61 pid_t gettid( void )
62 {
63 return syscall( __NR_gettid );
64 }
66 void *thread_routine( void *arg )
67 {
68 int i;
69 int proc_num = (int)(long)arg;
70 cpu_set_t set;
71 int v1, v2,v3;
73 #if 0
74 CPU_ZERO( &set );
75 CPU_SET( proc_num, &set );
77 if (sched_setaffinity( gettid(), sizeof( cpu_set_t ), &set ))
78 {
79 perror( "sched_setaffinity" );
80 return NULL;
81 }
82 #endif
84 for (i = 0; i < INC_TO; i++)
85 {
87 v1 = netapi_timing_start();
88 netapi_atomic_add64(&global_int,1LL);
89 v1= netapi_timing_stop() - v1;
90 sched_yield();
91 v2 = netapi_timing_start();
92 blah+=1;
93 v2= netapi_timing_stop() - v2;
95 v3 = netapi_timing_start();
96 blah2+=1;
97 v3= netapi_timing_stop() - v3;
98 if(i<10) { printf("thread %d -> a64 costs %d, tls costs %d simple++ costs %d\n", proc_num,v1,v2,v3);}
99 sched_yield();
100 }
101 printf("thead %d -> blah=%d\n",proc_num, blah);
103 printf("now try spin lock test. i'm thread %d, about to grab lock \n", proc_num);
105 //now we try the synch_lock_and_test
106 v1 = netapi_timing_start();
107 netapi_spinlock_lock(&spin_test);
108 v2 = netapi_timing_stop();
109 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);
110 sleep(1);
111 printf(" i'm back. i'm thread %d. i'm unlocking now\n",proc_num);
112 netapi_spinlock_unlock(&spin_test);
113 return NULL;
114 }
116 int main()
117 {
118 int procs = 0;
119 int i;
120 pthread_t *thrs;
121 printf("at start up\n");
123 // Getting number of CPUs
124 procs = (int)sysconf( _SC_NPROCESSORS_ONLN );
125 if (procs < 0)
126 {
127 perror( "sysconf" );
128 return -1;
129 }
130 printf(" num cpus = %d\n",procs);
131 if (procs==1) {procs+=1; printf("adding 2nd 'core' \n");}
132 thrs = malloc( sizeof( pthread_t ) * procs );
133 if (thrs == NULL)
134 {
135 perror( "malloc" );
136 return -1;
137 }
139 //initialize spinlock
140 netapi_spinlock_init(&spin_test);
141 printf( "Starting %d threads...\n", procs );
143 for (i = 0; i < procs; i++)
144 {
145 if (pthread_create( &thrs[i], NULL, thread_routine,
146 (void *)(long)i ))
147 {
148 perror( "pthread_create" );
149 procs = i;
150 break;
151 }
152 }
154 for (i = 0; i < procs; i++)
155 pthread_join( thrs[i], NULL );
157 free( thrs );
159 printf( "global_int value is: %lld bare global_int is %d\n",
160 global_int.val, blah2 );
161 printf( "Expected value is: %d\n", INC_TO * procs );
163 return 0;
164 }