|  | @@ -21,12 +21,50 @@
 | 
	
		
			
				|  |  |  #ifndef _PT_MACHINE_H
 | 
	
		
			
				|  |  |  #define _PT_MACHINE_H   1
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#include <features.h>
 | 
	
		
			
				|  |  | +#include <sys/syscall.h>
 | 
	
		
			
				|  |  | +#include <unistd.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifndef PT_EI
 | 
	
		
			
				|  |  |  # define PT_EI __extern_always_inline
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#if defined(__thumb__)
 | 
	
		
			
				|  |  | +#if defined(__USE_LDREXSTREX__)
 | 
	
		
			
				|  |  | +PT_EI long int ldrex(int *spinlock)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	long int ret;
 | 
	
		
			
				|  |  | +	__asm__ __volatile__(
 | 
	
		
			
				|  |  | +		"ldrex %0, [%1]\n"
 | 
	
		
			
				|  |  | +		: "=r"(ret)
 | 
	
		
			
				|  |  | +		: "r"(spinlock) : "memory");
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +PT_EI long int strex(int val, int *spinlock)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	long int ret;
 | 
	
		
			
				|  |  | +	__asm__ __volatile__(
 | 
	
		
			
				|  |  | +		"strex %0, %1, [%2]\n"
 | 
	
		
			
				|  |  | +		: "=r"(ret)
 | 
	
		
			
				|  |  | +		: "r" (val), "r"(spinlock) : "memory");
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* Spinlock implementation; required.  */
 | 
	
		
			
				|  |  | +PT_EI long int
 | 
	
		
			
				|  |  | +testandset (int *spinlock)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  register unsigned int ret;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  do {
 | 
	
		
			
				|  |  | +	  ret = ldrex(spinlock);
 | 
	
		
			
				|  |  | +  } while (strex(1, spinlock));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#else /* __USE_LDREXSTREX__ */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /* This will not work on ARM1 or ARM2 because SWP is lacking on those
 | 
	
		
			
				|  |  |     machines.  Unfortunately we have no way to detect this at compile
 | 
	
		
			
				|  |  |     time; let's hope nobody tries to use one.  */
 | 
	
	
		
			
				|  | @@ -36,8 +74,6 @@ PT_EI long int testandset (int *spinlock);
 | 
	
		
			
				|  |  |  PT_EI long int testandset (int *spinlock)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    register unsigned int ret;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -#if defined(__thumb__)
 | 
	
		
			
				|  |  |    void *pc;
 | 
	
		
			
				|  |  |    __asm__ __volatile__(
 | 
	
		
			
				|  |  |  	".align 0\n"
 | 
	
	
		
			
				|  | @@ -50,15 +86,21 @@ PT_EI long int testandset (int *spinlock)
 | 
	
		
			
				|  |  |  	"\t.force_thumb"
 | 
	
		
			
				|  |  |  	: "=r"(ret), "=r"(pc)
 | 
	
		
			
				|  |  |  	: "0"(1), "r"(spinlock));
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  | +  return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#else /* __thumb__ */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +PT_EI long int testandset (int *spinlock);
 | 
	
		
			
				|  |  | +PT_EI long int testandset (int *spinlock)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  register unsigned int ret;
 | 
	
		
			
				|  |  |    __asm__ __volatile__("swp %0, %1, [%2]"
 | 
	
		
			
				|  |  |  		       : "=r"(ret)
 | 
	
		
			
				|  |  |  		       : "0"(1), "r"(spinlock));
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    return ret;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* Get some notion of the current stack.  Need not be exactly the top
 | 
	
		
			
				|  |  |     of the stack, just something somewhere in the current frame.  */
 |