File: lock.h

package info (click to toggle)
crafty 19.15-1
  • links: PTS
  • area: non-free
  • in suites: sarge
  • size: 2,488 kB
  • ctags: 3,374
  • sloc: ansic: 28,852; cpp: 5,834; makefile: 431; sh: 108; perl: 30
file content (139 lines) | stat: -rw-r--r-- 4,800 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#if defined(SMP)

#undef Pause
#define Pause()

/*
 *******************************************************************************
 *                                                                             *
 *  this is a Microsoft windows-based operating system.                        *
 *                                                                             *
 *******************************************************************************
 */
#if defined(_WIN32) || defined(_WIN64)

#  define pthread_attr_t  HANDLE
#  define pthread_t       HANDLE
#  define thread_t        HANDLE
#  define tfork(t,f,p)    NumaStartThread((void *)(f),(void *)(p))

extern pthread_t NumaStartThread(void *func, void *args);

#if ((defined (_M_IA64) || defined (_M_AMD64)) && !defined(NT_INTEREX))

#  include <windows.h>

#  pragma intrinsic (_InterlockedExchange)

typedef volatile LONG lock_t[1];

#  define LockInit(v)      ((v)[0] = 0)
#  define LockFree(v)      ((v)[0] = 0)
#  define Unlock(v)        ((v)[0] = 0)

__forceinline void Lock(volatile LONG * hPtr)
{
  int       iValue;

  for (;;) {
    iValue = _InterlockedExchange((LPLONG) hPtr, 1);
    if (0 == iValue)
      return;
    while (*hPtr);
  }
}

#else                           /* NT non-Alpha/Intel, without assembler Lock() */

#  define lock_t           volatile int
#  define LockInit(v)      ((v) = 0)
#  define LockFree(v)      ((v) = 0)
#  define Lock(v)          do {                                         \
                             while(InterlockedExchange((LPLONG)&(v),1) != 0);  \
                           } while (0)
#  define Unlock(v)        ((v) = 0)

#endif                          /* architecture check */

#else
/*
 *******************************************************************************
 *                                                                             *
 *  this is a Unix-based operating system.                                     *
 *                                                                             *
 *  MUTEX forces us ot use the normal POSIX-threads MUTEX calls, which block   *
 *  when a resource is unavailable.  This is not great for performance.  If    *
 *  MUTEX is not defined, then we use inline assembly code for Lock/Unlock     *
 *  as needed.                                                                 *
 *                                                                             *
 *                                                                             *
 *******************************************************************************
 */

#if defined(MUTEX)

#  define Lock(v)          pthread_mutex_lock(&v)
#  define LockInit(v)      pthread_mutex_init(&v,0)
#  define LockFree(v)      pthread_mutex_destroy(&v)
#  define Unlock(v)        pthread_mutex_unlock(&v)
#  define lock_t           pthread_mutex_t

#elif defined(ALPHA)

#  if defined(__DECC)
#    include <machine/builtins.h>
#  endif
#  define lock_t           volatile long
#  define LockInit(v)      ((v) = 0)
#  define LockFree(v)      ((v) = 0)
#  define Lock(v)          __LOCK_LONG(&(v))
#  define Unlock(v)        __UNLOCK_LONG(&(v))

#else                           /* X86 */

#  undef Pause
#  define Pause() ({asm volatile ("pause");})

static void __inline__ LockX86(volatile int *lock)
{
  int       dummy;
  asm       __volatile__("1:          movl    $1, %0"    "\n\t"
                         "            xchgl   (%1), %0"  "\n\t"
                         "            testl   %0, %0"    "\n\t"
                         "            jz      3f"        "\n\t"
                         "2:          pause"             "\n\t"
                         "            movl    (%1), %0"  "\n\t"
                         "            testl   %0, %0"    "\n\t"
                         "            jnz     2b"        "\n\t"
                         "            jmp     1b"        "\n\t"
                         "3:"                            "\n\t"
                         :"=&q"(dummy)
                         :"q" (lock)
                         :"cc");
}

static void __inline__ UnlockX86(volatile int *lock)
{
  int       dummy;
  asm       __volatile__("movl    $0, (%1)":"=&q"(dummy)
                         :"q" (lock));
}

#  define LockInit(p)           (p=0)
#  define LockFree(p)           (p=0)
#  define Unlock(p)             (UnlockX86(&p))
#  define Lock(p)               (LockX86(&p))
#  define lock_t                volatile int

#endif                          /* MUTEX */

#define tfork(t,f,p)   pthread_create(&t,&pthread_attr,f,(void*) p)

#endif                          /* windows or unix */

#else
#  define LockInit(p)
#  define LockFree(p)
#  define Lock(p)
#  define Unlock(p)
#endif                          /*  SMP code */