Hello,
My compiler (gcc 4.4.2) did not like the assembly that was being used
for the current spinlock implementation, and I had some trouble figuring
out how the assembly actually worked. I implemented my own spin lock
that uses very little assembly and I attached it to this message.
Please let me know what the proper patching procedure is, and if you
want the code I will be happy to supply a patch.
Cheers,
Sam
/*********************************************************************
*
* Copyright (C) 2002-2003, 2006-2007, Karlsruhe University
* Copyright (C) 2010, Sam King, University of Illinois
*
* File path: arch/x86/sync.h
* Description: synchronization primitives for x86
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*
********************************************************************/
#ifndef __ARCH__X86__SYNC_H__
#define __ARCH__X86__SYNC_H__
#ifndef CONFIG_SMP
# error should not be included!
#endif
class spinlock_t
{
public:
void init(word_t val = 0)
{ this->_lock = val; }
void lock();
void unlock()
{ this->_lock = 0; }
bool is_locked()
{ return this->_lock; }
public: // to allow initializers
volatile word_t _lock;
};
#define DECLARE_SPINLOCK(name) extern spinlock_t name;
#define DEFINE_SPINLOCK(name) spinlock_t name = {_lock: 0}
#undef DEBUG_LOCK
#define SYNC_THRESHOLD 0x8000000
extern "C" void sync_debug (word_t lock);
inline word_t testandset_word(volatile word_t *spinlock)
{
word_t ret;
__asm__ __volatile__("xchg %0, %1"
: "=r"(ret), "=m"(*spinlock)
: "0"(1), "m"(*spinlock));
return ret;
}
INLINE void spinlock_t::lock()
{
#if defined(DEBUG_LOCK)
unsigned int count=0;
while(testandset_word(&(this->_lock))) {
if(count++ >= SYNC_THRESHOLD) {
sync_debug(this->_lock);
}
}
#else
while(testandset_word(&(this->_lock)))
;
#endif
}
#endif /* !__ARCH__X86__SYNC_H__ */