1#ifndef MY_CPU_INCLUDED
2#define MY_CPU_INCLUDED
3/* Copyright (c) 2013, MariaDB foundation Ab and SkySQL
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
17*/
18
19/* instructions for specific cpu's */
20
21/*
22 Macros for adjusting thread priority (hardware multi-threading)
23 The defines are the same ones used by the linux kernel
24*/
25
26#ifdef _ARCH_PWR8
27#include <sys/platform/ppc.h>
28/* Very low priority */
29#define HMT_very_low() __ppc_set_ppr_very_low()
30/* Low priority */
31#define HMT_low() __ppc_set_ppr_low()
32/* Medium low priority */
33#define HMT_medium_low() __ppc_set_ppr_med_low()
34/* Medium priority */
35#define HMT_medium() __ppc_set_ppr_med()
36/* Medium high priority */
37#define HMT_medium_high() __ppc_set_ppr_med_high()
38/* High priority */
39#define HMT_high() asm volatile("or 3,3,3")
40#else
41#define HMT_very_low()
42#define HMT_low()
43#define HMT_medium_low()
44#define HMT_medium()
45#define HMT_medium_high()
46#define HMT_high()
47#endif
48
49
50static inline void MY_RELAX_CPU(void)
51{
52#ifdef HAVE_PAUSE_INSTRUCTION
53 /*
54 According to the gcc info page, asm volatile means that the
55 instruction has important side-effects and must not be removed.
56 Also asm volatile may trigger a memory barrier (spilling all registers
57 to memory).
58 */
59#ifdef __SUNPRO_CC
60 asm ("pause" );
61#else
62 __asm__ __volatile__ ("pause");
63#endif
64
65#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION)
66 __asm__ __volatile__ ("rep; nop");
67#elif defined _WIN32
68 /*
69 In the Win32 API, the x86 PAUSE instruction is executed by calling
70 the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
71 independent way by using YieldProcessor.
72 */
73 YieldProcessor();
74#elif defined(_ARCH_PWR8)
75 __ppc_get_timebase();
76#else
77 int32 var, oldval = 0;
78 my_atomic_cas32_strong_explicit(&var, &oldval, 1, MY_MEMORY_ORDER_RELAXED,
79 MY_MEMORY_ORDER_RELAXED);
80#endif
81}
82
83
84/*
85 LF_BACKOFF should be used to improve performance on hyperthreaded CPUs. Intel
86 recommends to use it in spin loops also on non-HT machines to reduce power
87 consumption (see e.g http://softwarecommunity.intel.com/articles/eng/2004.htm)
88
89 Running benchmarks for spinlocks implemented with InterlockedCompareExchange
90 and YieldProcessor shows that much better performance is achieved by calling
91 YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
92 loop count in the range 200-300 brought best results.
93*/
94
95static inline int LF_BACKOFF(void)
96{
97 int i;
98 for (i= 0; i < 200; i++)
99 MY_RELAX_CPU();
100 return 1;
101}
102#endif
103