|   | 1 | = 目標 = | 
                  
                          |   | 2 |  * 以 gcc 編譯 spin_or_mutex.c | 
                  
                          |   | 3 |  * 編輯configure.ac makefile.am | 
                  
                          |   | 4 | == spin_or_mutex.c == | 
                  
                          |   | 5 | {{{ | 
                  
                          |   | 6 | #!c | 
                  
                          |   | 7 | //export LIBRARY_PATH=/usr/lib/i386-linux-gnu/ | 
                  
                          |   | 8 | #include <stdio.h> | 
                  
                          |   | 9 | #include <pthread.h> | 
                  
                          |   | 10 | #include <unistd.h> | 
                  
                          |   | 11 | #include <sys/syscall.h> | 
                  
                          |   | 12 | #include <errno.h> | 
                  
                          |   | 13 | #include <sys/time.h> | 
                  
                          |   | 14 |  | 
                  
                          |   | 15 | #define LOOPS 10000000 | 
                  
                          |   | 16 |  | 
                  
                          |   | 17 | #ifdef USE_SPINLOCK | 
                  
                          |   | 18 | pthread_spinlock_t spinlock; | 
                  
                          |   | 19 | #else | 
                  
                          |   | 20 | pthread_mutex_t mutex; | 
                  
                          |   | 21 | #endif | 
                  
                          |   | 22 |  | 
                  
                          |   | 23 | pid_t gettid() { return syscall( __NR_gettid ); } | 
                  
                          |   | 24 |  | 
                  
                          |   | 25 | char data[LOOPS]; | 
                  
                          |   | 26 |  | 
                  
                          |   | 27 | void *consumer(void *ptr) | 
                  
                          |   | 28 | { | 
                  
                          |   | 29 |     int i = 0; | 
                  
                          |   | 30 |  | 
                  
                          |   | 31 |     printf("Consumer TID %lu\n", (unsigned long)gettid()); | 
                  
                          |   | 32 |  | 
                  
                          |   | 33 |     while (1) | 
                  
                          |   | 34 |     { | 
                  
                          |   | 35 | #ifdef USE_SPINLOCK | 
                  
                          |   | 36 |         pthread_spin_lock(&spinlock); | 
                  
                          |   | 37 | #else | 
                  
                          |   | 38 |         pthread_mutex_lock(&mutex); | 
                  
                          |   | 39 | #endif | 
                  
                          |   | 40 |  | 
                  
                          |   | 41 |         if (i > LOOPS) | 
                  
                          |   | 42 |         { | 
                  
                          |   | 43 | #ifdef USE_SPINLOCK | 
                  
                          |   | 44 |             pthread_spin_unlock(&spinlock); | 
                  
                          |   | 45 | #else | 
                  
                          |   | 46 |             pthread_mutex_unlock(&mutex); | 
                  
                          |   | 47 | #endif | 
                  
                          |   | 48 |             break; | 
                  
                          |   | 49 |         } | 
                  
                          |   | 50 |  | 
                  
                          |   | 51 |          | 
                  
                          |   | 52 |         data[i] = 0; | 
                  
                          |   | 53 |         i++; | 
                  
                          |   | 54 |  | 
                  
                          |   | 55 | #ifdef USE_SPINLOCK | 
                  
                          |   | 56 |         pthread_spin_unlock(&spinlock); | 
                  
                          |   | 57 | #else | 
                  
                          |   | 58 |         pthread_mutex_unlock(&mutex); | 
                  
                          |   | 59 | #endif | 
                  
                          |   | 60 |     } | 
                  
                          |   | 61 |  | 
                  
                          |   | 62 |     return NULL; | 
                  
                          |   | 63 | } | 
                  
                          |   | 64 |  | 
                  
                          |   | 65 | int main() | 
                  
                          |   | 66 | { | 
                  
                          |   | 67 |     int i; | 
                  
                          |   | 68 |     pthread_t thr1, thr2; | 
                  
                          |   | 69 |     struct timeval tv1, tv2; | 
                  
                          |   | 70 |  | 
                  
                          |   | 71 | #ifdef USE_SPINLOCK | 
                  
                          |   | 72 |     pthread_spin_init(&spinlock, 0); | 
                  
                          |   | 73 | #else | 
                  
                          |   | 74 |     pthread_mutex_init(&mutex, NULL); | 
                  
                          |   | 75 | #endif | 
                  
                          |   | 76 |  | 
                  
                          |   | 77 |     // Creating the list content... | 
                  
                          |   | 78 |     for (i = 0; i < LOOPS; i++){ | 
                  
                          |   | 79 |         data[i] = 1;     | 
                  
                          |   | 80 |     } | 
                  
                          |   | 81 |          | 
                  
                          |   | 82 |  | 
                  
                          |   | 83 |     // Measuring time before starting the threads... | 
                  
                          |   | 84 |     gettimeofday(&tv1, NULL); | 
                  
                          |   | 85 |  | 
                  
                          |   | 86 |     pthread_create(&thr1, NULL, consumer, NULL); | 
                  
                          |   | 87 |     pthread_create(&thr2, NULL, consumer, NULL); | 
                  
                          |   | 88 |  | 
                  
                          |   | 89 |     pthread_join(thr1, NULL); | 
                  
                          |   | 90 |     pthread_join(thr2, NULL); | 
                  
                          |   | 91 |  | 
                  
                          |   | 92 |     // Measuring time after threads finished... | 
                  
                          |   | 93 |     gettimeofday(&tv2, NULL); | 
                  
                          |   | 94 |  | 
                  
                          |   | 95 |     if (tv1.tv_usec > tv2.tv_usec) | 
                  
                          |   | 96 |     { | 
                  
                          |   | 97 |         tv2.tv_sec--; | 
                  
                          |   | 98 |         tv2.tv_usec += 1000000; | 
                  
                          |   | 99 |     } | 
                  
                          |   | 100 |  | 
                  
                          |   | 101 |     printf("Result - %ld.%ld\n", tv2.tv_sec - tv1.tv_sec, | 
                  
                          |   | 102 |         tv2.tv_usec - tv1.tv_usec); | 
                  
                          |   | 103 |  | 
                  
                          |   | 104 | #ifdef USE_SPINLOCK | 
                  
                          |   | 105 |     pthread_spin_destroy(&spinlock); | 
                  
                          |   | 106 | #else | 
                  
                          |   | 107 |     pthread_mutex_destroy(&mutex); | 
                  
                          |   | 108 | #endif | 
                  
                          |   | 109 |  | 
                  
                          |   | 110 |     return 0; | 
                  
                          |   | 111 | } | 
                  
                          |   | 112 |  | 
                  
                          |   | 113 | }}} | 
                  
                          |   | 114 |  | 
                  
                          |   | 115 | == 以 gcc 編譯 spin_or_mutex.c == | 
                  
                          |   | 116 | === 編輯Makefile === | 
                  
                          |   | 117 |  | 
                  
                          |   | 118 | {{{ | 
                  
                          |   | 119 | #!text | 
                  
                          |   | 120 | all: | 
                  
                          |   | 121 |         gcc spin_or_mutex.c -o spin_or_mutex | 
                  
                          |   | 122 |  | 
                  
                          |   | 123 | clean: | 
                  
                          |   | 124 |         rm -f spin_or_mutex | 
                  
                          |   | 125 | }}} | 
                  
                          |   | 126 |  | 
                  
                          |   | 127 | == 執行 == | 
                  
                          |   | 128 | {{{ | 
                  
                          |   | 129 | $ make | 
                  
                          |   | 130 | gcc spin_or_mutex.c -o spin_or_mutex | 
                  
                          |   | 131 | /tmp/ccTHYKpZ.o: In function `main': | 
                  
                          |   | 132 | spin_or_mutex.c:(.text+0xf2): undefined reference to `pthread_create' | 
                  
                          |   | 133 | spin_or_mutex.c:(.text+0x116): undefined reference to `pthread_create' | 
                  
                          |   | 134 | spin_or_mutex.c:(.text+0x12a): undefined reference to `pthread_join' | 
                  
                          |   | 135 | spin_or_mutex.c:(.text+0x13e): undefined reference to `pthread_join' | 
                  
                          |   | 136 | collect2: ld returned 1 exit status | 
                  
                          |   | 137 | make: *** [all] Error 1 | 
                  
                          |   | 138 | }}} | 
                  
                          |   | 139 |  | 
                  
                          |   | 140 |  | 
                  
                          |   | 141 | === 修改 Makefile === | 
                  
                          |   | 142 | {{{ | 
                  
                          |   | 143 | #!text | 
                  
                          |   | 144 | all: | 
                  
                          |   | 145 |         gcc -lpthread  spin_or_mutex.c -o spin_or_mutex | 
                  
                          |   | 146 |  | 
                  
                          |   | 147 | clean: | 
                  
                          |   | 148 |         rm -f spin_or_mutex | 
                  
                          |   | 149 |  | 
                  
                          |   | 150 | }}} | 
                  
                          |   | 151 |  | 
                  
                          |   | 152 | == 執行 == | 
                  
                          |   | 153 | {{{ | 
                  
                          |   | 154 | $ make | 
                  
                          |   | 155 | $ ./spin_or_mutex | 
                  
                          |   | 156 | }}} | 
                  
                          |   | 157 |  | 
                  
                          |   | 158 |  * Done! | 
                  
                          |   | 159 |  | 
                  
                          |   | 160 | == 編輯configure.ac makefile.am == | 
                  
                          |   | 161 | == 執行 == | 
                  
                          |   | 162 | {{{ | 
                  
                          |   | 163 | $ autoscan  | 
                  
                          |   | 164 | $ mv configure.scan configure.ac | 
                  
                          |   | 165 | $ mv Makefile Makefile.in | 
                  
                          |   | 166 | $ autoconf  | 
                  
                          |   | 167 | $ autoheader  | 
                  
                          |   | 168 | $ ./configure  | 
                  
                          |   | 169 | $ make clean  | 
                  
                          |   | 170 | }}} | 
                  
                          |   | 171 |  | 
                  
                          |   | 172 | == 修改spin_or_mutex.c == | 
                  
                          |   | 173 | {{{ | 
                  
                          |   | 174 | #!c | 
                  
                          |   | 175 | #include "config.h" | 
                  
                          |   | 176 | // 以下略 | 
                  
                          |   | 177 | }}} | 
                  
                          |   | 178 |  | 
                  
                          |   | 179 | == 新增Makefile.am == | 
                  
                          |   | 180 | {{{ | 
                  
                          |   | 181 | #!text | 
                  
                          |   | 182 | bin_PROGRAMS=spin_or_mutex | 
                  
                          |   | 183 | spin_or_mutex_SOURCES=spin_or_mutex.c | 
                  
                          |   | 184 | }}} | 
                  
                          |   | 185 | == 產生make檔 == | 
                  
                          |   | 186 | {{{ | 
                  
                          |   | 187 | $ aclocal | 
                  
                          |   | 188 | $ autoconf | 
                  
                          |   | 189 | $ automake | 
                  
                          |   | 190 | }}} | 
                  
                          |   | 191 |  * 修改error | 
                  
                          |   | 192 | {{{ | 
                  
                          |   | 193 | #!text | 
                  
                          |   | 194 | AM_CONDITIONAL | 
                  
                          |   | 195 | AC_PROG_CC | 
                  
                          |   | 196 | AC_PROG_CXX  | 
                  
                          |   | 197 | AC_PROG_OBJC | 
                  
                          |   | 198 | AM_PROG_AS  | 
                  
                          |   | 199 | AM_PROG_GCJ  | 
                  
                          |   | 200 | AM_PROG_UPC | 
                  
                          |   | 201 | }}} | 
                  
                          |   | 202 |  | 
                  
                          |   | 203 |  * ./confifure | 
                  
                          |   | 204 | {{{ | 
                  
                          |   | 205 | $ ./configure | 
                  
                          |   | 206 | $ make | 
                  
                          |   | 207 | make  all-am | 
                  
                          |   | 208 | make[1]: Entering directory `/home/shunfa/test/P1_Thomas' | 
                  
                          |   | 209 | source='spin_or_mutex.c' object='spin_or_mutex.o' libtool=no \ | 
                  
                          |   | 210 |         DEPDIR=.deps depmode=none /bin/bash ./depcomp \ | 
                  
                          |   | 211 |         gcc -DHAVE_CONFIG_H -I.     -g -O2 -c spin_or_mutex.c | 
                  
                          |   | 212 | gcc  -g -O2   -o spin_or_mutex spin_or_mutex.o  -lpthread  | 
                  
                          |   | 213 | spin_or_mutex.o: In function `_start': | 
                  
                          |   | 214 | (.text+0x0): multiple definition of `_start' | 
                  
                          |   | 215 | /usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/crt1.o:(.text+0x0): first defined here | 
                  
                          |   | 216 | spin_or_mutex.o:(.rodata+0x0): multiple definition of `_fp_hw' | 
                  
                          |   | 217 | /usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/crt1.o:(.rodata+0x0): first defined here | 
                  
                          |   | 218 | spin_or_mutex.o: In function `_fini': | 
                  
                          |   | 219 | (.fini+0x0): multiple definition of `_fini' | 
                  
                          |   | 220 | /usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/crti.o:(.fini+0x0): first defined here | 
                  
                          |   | 221 | spin_or_mutex.o:(.rodata+0x4): multiple definition of `_IO_stdin_used' | 
                  
                          |   | 222 | /usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/crt1.o:(.rodata.cst4+0x0): first defined here | 
                  
                          |   | 223 | spin_or_mutex.o: In function `__data_start': | 
                  
                          |   | 224 | (.data+0x0): multiple definition of `__data_start' | 
                  
                          |   | 225 | /usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/crt1.o:(.data+0x0): first defined here | 
                  
                          |   | 226 | spin_or_mutex.o: In function `__data_start': | 
                  
                          |   | 227 | (.data+0x4): multiple definition of `__dso_handle' | 
                  
                          |   | 228 | /usr/lib/gcc/i486-linux-gnu/4.4.5/crtbegin.o:(.data+0x0): first defined here | 
                  
                          |   | 229 | spin_or_mutex.o: In function `_init': | 
                  
                          |   | 230 | (.init+0x0): multiple definition of `_init' | 
                  
                          |   | 231 | /usr/lib/gcc/i486-linux-gnu/4.4.5/../../../../lib/crti.o:(.init+0x0): first defined here | 
                  
                          |   | 232 | /usr/lib/gcc/i486-linux-gnu/4.4.5/crtend.o:(.dtors+0x0): multiple definition of `__DTOR_END__' | 
                  
                          |   | 233 | spin_or_mutex.o:(.dtors+0x4): first defined here | 
                  
                          |   | 234 | collect2: ld returned 1 exit status | 
                  
                          |   | 235 | make[1]: *** [spin_or_mutex] Error 1 | 
                  
                          |   | 236 | make[1]: Leaving directory `/home/shunfa/test/P1_Thomas' | 
                  
                          |   | 237 | make: *** [all] Error 2 | 
                  
                          |   | 238 | }}} |