mips_lock.c

00001 /*
00002  *
00003  *  simple locking test program
00004  *  (no paralles stuff)
00005  * 
00006  *  Compile with: gcc -D__CPU_i386 -O3 on x86 machines and
00007  *                gcc -mips2 -O2 -D__CPU_mips  on mips machines.
00008  *  -- andrei
00009  *
00010  *  
00011  */
00012 
00013 #include <stdio.h>
00014 
00015 typedef volatile int fl_lock_t;
00016 
00017 
00018 
00019 int tsl(fl_lock_t* lock)
00020 {
00021         long val;
00022         
00023 #ifdef __CPU_mips
00024         long tmp=0;
00025         
00026         asm volatile(
00027                 ".set noreorder\n\t"
00028                 "1:  ll %1, %2   \n\t"
00029                 "    li %0, 1 \n\t"
00030                 "    sc %0, %2  \n\t"
00031                 "    beqz %0, 1b \n\t"
00032                 "    nop \n\t"
00033                 ".set reorder\n\t"
00034                 : "=&r" (tmp), "=&r" (val), "=m" (*lock) 
00035                 : "0" (tmp), "m" (*lock) 
00036                 : "cc"
00037         );
00038 #elif defined __CPU_i386
00039         val=1;
00040         asm volatile( 
00041                 " xchg %b1, %0" : "=q" (val), "=m" (*lock) : "0" (val) 
00042         );
00043 #else
00044 #error "cpu type not defined, add -D__CPU_<type> when compiling"
00045 #endif
00046         
00047         return val;
00048 }
00049 
00050 
00051 
00052 void release_lock(fl_lock_t* lock)
00053 {
00054 #ifdef __CPU_mips
00055         int tmp;
00056         tmp=0;
00057         asm volatile(
00058                 ".set noreorder \n\t"
00059                 "    sync \n\t"
00060                 "    sw $0, %0 \n\t"
00061                 ".set reorder \n\t"
00062                 : /*no output*/  : "m" (*lock) : "memory"
00063         );
00064 #elif defined __CPU_i386
00065         asm volatile(
00066                 " movb $0, (%0)" : /*no output*/ : "r"(lock): "memory"
00067         ); 
00068 #else
00069 #error "cpu type not defined, add -D__CPU_<type> when compiling"
00070 #endif
00071 }
00072 
00073 
00074 
00075 int main(int argc, char** argv)
00076 {
00077         fl_lock_t lock;
00078         int r;
00079         
00080         lock=0;
00081         printf("starting locking basic tests...\n");
00082         
00083         r=tsl(&lock);
00084         printf(" tsl should return 0                 ... %d\n", r);
00085         printf("     lock should be 1 now            ... %d\n", lock);
00086         r=tsl(&lock);
00087         printf(" tsl should return 1                 ... %d\n", r);
00088         printf("     lock should still be 1 now      ... %d\n", lock);
00089         release_lock(&lock);
00090         printf(" release_lock: lock should be 0 now  ... %d\n", lock);
00091         printf("trying tsl once more...\n");
00092         r=tsl(&lock);
00093         printf(" tsl should return 0                 ... %d\n", r);
00094         printf("     lock should be 1 now            ... %d\n", lock);
00095         printf("\ndone.\n");
00096         return 0;
00097 }