eca7f442 |
/*
* fast arhitecture specific locking
*
* $Id$
*
*
|
7dd0b342 |
*
* Copyright (C) 2001-2003 Fhg Fokus
*
* This file is part of ser, a free SIP server.
*
* ser is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* For a license to use the ser software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* ser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
eca7f442 |
*/
|
c751da14 |
/*
*
*
* 2003-01-16 added PPC locking code contributed by Dinos Dorkofikis
* <kdor@intranet.gr>
*
*/
|
eca7f442 |
|
7dd0b342 |
|
eca7f442 |
#ifndef fastlock_h
#define fastlock_h
|
e61f4ba3 |
#ifdef HAVE_SCHED_YIELD
|
eca7f442 |
#include <sched.h>
|
e61f4ba3 |
#else
#include <unistd.h>
/* fake sched_yield */
#define sched_yield() sleep(0)
#endif
|
eca7f442 |
|
2781889b |
typedef volatile int fl_lock_t;
|
eca7f442 |
#define init_lock( l ) (l)=0
/*test and set lock, ret 1 if lock held by someone else, 0 otherwise*/
|
2781889b |
inline static int tsl(fl_lock_t* lock)
|
eca7f442 |
{
|
a0bb0a26 |
int val;
|
30f1f956 |
|
087d0976 |
#ifdef __CPU_i386
|
cd5c8c64 |
#ifdef NOSMP
val=0;
asm volatile(
|
f9c47c02 |
" btsl $0, %1 \n\t"
|
cd5c8c64 |
" adcl $0, %0 \n\t"
|
cd87f178 |
: "=q" (val), "=m" (*lock) : "0"(val) : "memory", "cc" /* "cc" */
|
cd5c8c64 |
);
#else
|
eca7f442 |
val=1;
asm volatile(
|
cd87f178 |
" xchg %b1, %0" : "=q" (val), "=m" (*lock) : "0" (val) : "memory"
|
eca7f442 |
);
|
cd5c8c64 |
#endif /*NOSMP*/
|
85f1f3ee |
#elif defined __CPU_sparc64
|
c4217e61 |
asm volatile(
"ldstub [%1], %0 \n\t"
|
cd5c8c64 |
#ifndef NOSMP
|
c4217e61 |
"membar #StoreStore | #StoreLoad \n\t"
|
cd5c8c64 |
#endif
|
c4217e61 |
: "=r"(val) : "r"(lock):"memory"
);
|
cd87f178 |
|
087d0976 |
#elif defined __CPU_arm
|
cd87f178 |
asm volatile(
|
5161d446 |
"# here \n\t"
"swpb %0, %1, [%2] \n\t"
: "=r" (val)
: "r"(1), "r" (lock) : "memory"
|
cd87f178 |
);
|
523768d2 |
#elif defined __CPU_ppc
asm volatile(
"1: lwarx %0, 0, %2\n\t"
" cmpwi %0, 0\n\t"
" bne 0f\n\t"
" stwcx. %1, 0, %2\n\t"
" bne- 1b\n\t"
"0:\n\t"
: "=r" (val)
: "r"(1), "b" (lock) :
"memory", "cc"
);
|
43cfbe04 |
#else
#error "unknown arhitecture"
|
c4217e61 |
#endif
|
43cfbe04 |
return val;
|
eca7f442 |
}
|
2781889b |
inline static void get_lock(fl_lock_t* lock)
|
eca7f442 |
{
|
30f1f956 |
#ifdef ADAPTIVE_WAIT
int i=ADAPTIVE_WAIT_LOOPS;
#endif
|
eca7f442 |
while(tsl(lock)){
|
30f1f956 |
#ifdef BUSY_WAIT
#elif defined ADAPTIVE_WAIT
if (i>0) i--;
else sched_yield();
#else
|
eca7f442 |
sched_yield();
|
30f1f956 |
#endif
|
eca7f442 |
}
}
|
2781889b |
inline static void release_lock(fl_lock_t* lock)
|
eca7f442 |
{
|
087d0976 |
#ifdef __CPU_i386
|
43cfbe04 |
char val;
|
eca7f442 |
val=0;
asm volatile(
|
da87d067 |
" movb $0, (%0)" : /*no output*/ : "r"(lock): "memory"
/*" xchg %b0, %1" : "=q" (val), "=m" (*lock) : "0" (val) : "memory"*/
|
bf0fab3f |
);
|
85f1f3ee |
#elif defined __CPU_sparc64
|
c4217e61 |
asm volatile(
|
cd5c8c64 |
#ifndef NOSMP
|
c4217e61 |
"membar #LoadStore | #StoreStore \n\t" /*is this really needed?*/
|
cd5c8c64 |
#endif
|
c4217e61 |
"stb %%g0, [%0] \n\t"
: /*no output*/
: "r" (lock)
: "memory"
|
eca7f442 |
);
|
087d0976 |
#elif defined __CPU_arm
|
cd87f178 |
asm volatile(
|
5161d446 |
" str %0, [%1] \n\r"
: /*no outputs*/
: "r"(0), "r"(lock)
: "memory"
|
cd87f178 |
);
|
523768d2 |
#elif defined __CPU_ppc
asm volatile(
"sync\n\t"
"stw %0, 0(%1)\n\t"
: /* no output */
: "r"(0), "b" (lock)
: "memory"
);
*lock = 0;
|
43cfbe04 |
#else
#error "unknown arhitecture"
|
c4217e61 |
#endif
|
eca7f442 |
}
#endif
|