source: rtems/cpukit/score/cpu/i386/rtems/score/cpusmplock.h @ e358088

4.115
Last change on this file since e358088 was e358088, checked in by Sebastian Huber <sebastian.huber@…>, on 05/28/13 at 08:54:46

smp: New SMP lock API

Move the SMP lock implementation to the CPU port. An optimal SMP lock
implementation is highly architecture dependent. For example the memory
models may be fundamentally different.

The new SMP lock API has a flaw. It does not provide the ability to use
a local context for acquire and release pairs. Such a context is
necessary to implement for example the Mellor-Crummey and Scott (MCS)
locks. The SMP lock is currently used in _Thread_Disable_dispatch() and
_Thread_Enable_dispatch() and makes them to a giant lock acquire and
release. Since these functions do not pass state information via a
local context there is currently no use case for such a feature.

  • Property mode set to 100644
File size: 1.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreSMPLockI386
5 *
6 * @brief i386 SMP Lock Implementation
7 */
8
9/*
10 * COPYRIGHT (c) 1989-2011.
11 * On-Line Applications Research Corporation (OAR).
12 *
13 * Copyright (c) 2013 embedded brains GmbH
14 *
15 * The license and distribution terms for this file may be
16 * found in the file LICENSE in this distribution or at
17 * http://www.rtems.com/license/LICENSE.
18 */
19
20#ifndef _RTEMS_SCORE_I386_SMPLOCK_H
21#define _RTEMS_SCORE_I386_SMPLOCK_H
22
23#include <rtems/score/cpu.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif /* __cplusplus */
28
29/**
30 * @defgroup ScoreSMPLockI386 i386 SMP Locks
31 *
32 * @ingroup ScoreSMPLock
33 *
34 * The implementation is Test and Swap.
35 *
36 * @{
37 */
38
39typedef struct {
40  uint32_t locked;
41} CPU_SMP_lock_Control;
42
43#define CPU_SMP_LOCK_INITIALIZER { 0 }
44
45static inline void _CPU_SMP_lock_Initialize( CPU_SMP_lock_Control *lock )
46{
47  lock->locked = 0;
48}
49
50static inline uint32_t _I386_Atomic_swap(
51  volatile uint32_t *address,
52  uint32_t value
53)
54{
55  uint32_t previous;
56
57  asm volatile(
58    "lock; xchgl %0, %1"
59    : "+m" (*address), "=a" (previous)
60    : "1" (value)
61    : "cc"
62  );
63
64  return previous;
65}
66
67static inline void _CPU_SMP_lock_Acquire( CPU_SMP_lock_Control *lock )
68{
69  do {
70    while ( lock->locked ) {
71      /* Do nothing */
72    }
73  } while ( _I386_Atomic_swap( &lock->locked, 1 ) );
74}
75
76static inline void _CPU_SMP_lock_Release( CPU_SMP_lock_Control *lock )
77{
78  RTEMS_COMPILER_MEMORY_BARRIER();
79  lock->locked = 0;
80}
81
82#define _CPU_SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
83  do { \
84    _CPU_ISR_Disable( isr_cookie ); \
85    _CPU_SMP_lock_Acquire( lock ); \
86  } while (0)
87
88#define _CPU_SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
89  do { \
90    _CPU_SMP_lock_Release( lock ); \
91    _CPU_ISR_Enable( isr_cookie ); \
92  } while (0)
93
94/**@}*/
95
96#ifdef __cplusplus
97}
98#endif /* __cplusplus */
99
100#endif /* _RTEMS_SCORE_I386_SMPLOCK_H */
Note: See TracBrowser for help on using the repository browser.