Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
T
tarantool
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
core
tarantool
Commits
40dc77b6
Commit
40dc77b6
authored
13 years ago
by
p.cherenkov
Browse files
Options
Downloads
Patches
Plain Diff
[Speed up wal write] added access to hardware-enabled CRC32 and cpu feature polling
parent
2c4bfacb
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
core/cpu_feature.m
+205
-0
205 additions, 0 deletions
core/cpu_feature.m
include/cpu_feature.h
+51
-0
51 additions, 0 deletions
include/cpu_feature.h
with
256 additions
and
0 deletions
core/cpu_feature.m
0 → 100644
+
205
−
0
View file @
40dc77b6
/*
*
Copyright
(
C
)
2010
Mail
.
RU
*
*
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
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
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
.
*/
#include
<
sys
/
types
.
h
>
#include
<
errno
.
h
>
#include
"cpu_feature.h"
enum
{
eAX
=
0
,
eBX
,
eCX
,
eDX
}
;
static
const
struct
cpuid
_
feature
{
unsigned
int
ri
;
u
_
int32
_
t
mask
;
}
cpu
_
ftr
[]
=
{
{
eDX
,
(
1
<<
28
)}
,
/*
HT
*/
{
eCX
,
(
1
<<
19
)}
,
/*
SSE
4.1
*/
{
eCX
,
(
1
<<
20
)}
,
/*
SSE
4.2
*/
{
eCX
,
(
1
<<
31
)}
/*
HYPERV
*/
}
;
static
const
size
_
t
LEN
_
cpu
_
ftr
=
sizeof
(
cpu
_
ftr
)
/
sizeof
(
cpu
_
ftr
[
0
])
;
#define
SCALE
_
F
sizeof
(
unsigned
long
)
#if
defined
(
__
x86
_
64
__
)
#define
REX
_
PRE
"0x48, "
#elif
defined
(
__
i386
__
)
#define
REX
_
PRE
#else
#error
"Only x86 and x86_64 architectures supported"
#endif
/*
hw
-
calculate
CRC32
per
byte
(
for
the
unaligned
portion
of
data
buffer
)
*/
static
u
_
int32
_
t
crc32c
_
hw
_
byte
(
u
_
int32
_
t
crc
,
unsigned
char
const
*
data
,
size
_
t
length
)
{
while
(
length
--
)
{
__
asm
__
__
volatile
__
(
".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1"
:
"=S"
(
crc
)
:
"0"
(
crc
)
,
"c"
(*data)
);
data++;
}
return crc;
}
/* hw-calculate CRC32 for the given data buffer
*/
u_int32_t
crc32c_hw(u_int32_t crc, unsigned char const *p, size_t len)
{
unsigned int iquotient = len / SCALE_F;
unsigned int iremainder = len % SCALE_F;
unsigned long *ptmp = (unsigned long *)
p
;
while
(
iquotient
--
)
{
__
asm
__
__
volatile
__
(
".byte 0xf2, "
REX
_
PRE
"0xf, 0x38, 0xf1, 0xf1;"
:
"=S"
(
crc
)
:
"0"
(
crc
)
,
"c"
(*ptmp)
);
ptmp++;
}
if (iremainder) {
crc = crc32c_hw_byte(crc, (unsigned char *)
ptmp
,
iremainder
)
;
}
return
crc
;
}
/*
toggle
x86
flag
-
register
bits
,
as
per
mask
return
flags
both
in
original
and
toggled
state
*/
static
void
toggle
_
x86
_
flags
(
long
mask
,
long
*
orig
,
long
*
toggled
)
{
long
forig
=
0
,
fres
=
0
;
#if
defined
(
__
i386
__
)
asm
(
"pushfl; popl %%eax; movl %%eax, %0; xorl %2, %%eax; "
"pushl %%eax; popfl; pushfl; popl %%eax; pushl %0; popfl "
:
"=r"
(
forig
)
,
"=a"
(
fres
)
:
"m"
(
mask
)
)
;
#elif
__
x86
_
64
__
asm
(
"pushfq; popq %%rax; movq %%rax, %0; xorq %2, %%rax; "
"pushq %%rax; popfq; pushfq; popq %%rax; pushq %0; popfq "
:
"=r"
(
forig
)
,
"=a"
(
fres
)
:
"m"
(
mask
)
)
;
#endif
if
(
orig
)
*
orig
=
forig
;
if
(
toggled
)
*
toggled
=
fres
;
return
;
}
/*
is
CPUID
instruction
available
?
*/
static
int
can
_
cpuid
()
{
long
of
=
-
1
,
tf
=
-
1
;
/*
x86
flag
register
masks
*/
enum
{
cpuf
_
AC
=
(
1
<<
18
)
,
/*
bit
18
*/
cpuf
_
ID
=
(
1
<<
21
)
/*
bit
21
*/
}
;
/*
check
if
AC
(
alignment
)
flag
could
be
toggled
:
if
not
-
it
'
s
i386
,
thus
no
CPUID
*/
toggle
_
x86
_
flags
(
cpuf
_
AC
,
&
of
,
&
tf
)
;
if
((
of
&
cpuf
_
AC
)
==
(
tf
&
cpuf
_
AC
))
{
return
0
;
}
/*
next
try
toggling
CPUID
(
ID
)
flag
*/
toggle
_
x86
_
flags
(
cpuf
_
ID
,
&
of
,
&
tf
)
;
if
((
of
&
cpuf
_
ID
)
==
(
tf
&
cpuf
_
ID
))
{
return
0
;
}
return
1
;
}
/*
retrieve
CPUID
data
using
info
as
the
EAX
key
*/
static
void
get
_
cpuid
(
long
info
,
long
*
eax
,
long
*
ebx
,
long
*
ecx
,
long
*
edx
)
{
*
eax
=
info
;
#if
defined
(
__
i386
__
)
asm
__
volatile
__
(
"movl %%ebx, %%edi; "
/*
must
save
ebx
for
32
-
bit
PIC
code
*/
"cpuid; "
"movl %%ebx, %%esi; "
"movl %%edi, %%ebx; "
:
"+a"
(*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
:
: "%edi"
);
#elif defined (__x86_64__)
asm __volatile__ (
"cpuid; "
: "+a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
);
#endif
}
/* return 1=feature is available, 0=unavailable, 0>(errno) = error */
int
cpu_has (unsigned int feature)
{
long info = 1, reg[4] = {0,0,0,0};
if (!can_cpuid ())
return -EINVAL;
if (feature > LEN_cpu_ftr)
return -ERANGE;
get_cpuid (info, ®[eAX], ®[eBX], ®[eCX], ®[eDX]);
return (reg[cpu_ftr[feature].ri] & cpu_ftr[feature].mask) ? 1 : 0;
}
/* __EOF__ */
This diff is collapsed.
Click to expand it.
include/cpu_feature.h
0 → 100644
+
51
−
0
View file @
40dc77b6
#ifndef TARANTOOL_CPU_FEATURES_H
#define TARANTOOL_CPU_FEATURES_H
/*
* Copyright (C) 2010 Mail.RU
*
* 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 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 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.
*/
#include
<sys/types.h>
/* CPU feature capabilities to use with cpu_has (feature) */
enum
{
cpuf_ht
=
0
,
cpuf_sse4_1
,
cpuf_sse4_2
,
cpuf_hypervisor
};
/* return 1=feature is available, 0=unavailable, -EINVAL = unsupported CPU,
-ERANGE = invalid feature
*/
int
cpu_has
(
unsigned
int
feature
);
/* hardware-calculate CRC32 for the given data buffer
* NB: requires 1 == cpu_has (cpuf_sse4_2),
* CALLING IT W/O CHECKING for sse4_2 CAN CAUSE SIGABRT
*/
u_int32_t
crc32c_hw
(
u_int32_t
crc
,
unsigned
char
const
*
p
,
size_t
len
);
#endif
/* TARANTOOL_CPU_FEATURES_H */
/* __EOF__ */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment