mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Ensure that there will be no strlen() calls for SSE checks
This commit is contained in:
parent
d4e7c90306
commit
9e3ff349eb
@ -10,6 +10,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <utility> /// pair
|
#include <utility> /// pair
|
||||||
|
|
||||||
#if !defined(ARCADIA_BUILD)
|
#if !defined(ARCADIA_BUILD)
|
||||||
@ -61,6 +62,7 @@ int mainEntryClickHouseStatus(int argc, char ** argv);
|
|||||||
int mainEntryClickHouseRestart(int argc, char ** argv);
|
int mainEntryClickHouseRestart(int argc, char ** argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -154,28 +156,29 @@ enum class InstructionFail
|
|||||||
AVX512 = 8
|
AVX512 = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * instructionFailToString(InstructionFail fail)
|
std::pair<const char *, size_t> instructionFailToString(InstructionFail fail)
|
||||||
{
|
{
|
||||||
switch (fail)
|
switch (fail)
|
||||||
{
|
{
|
||||||
|
#define ret(x) return std::make_pair(x, ARRAY_SIZE(x) - 1)
|
||||||
case InstructionFail::NONE:
|
case InstructionFail::NONE:
|
||||||
return "NONE";
|
ret("NONE");
|
||||||
case InstructionFail::SSE3:
|
case InstructionFail::SSE3:
|
||||||
return "SSE3";
|
ret("SSE3");
|
||||||
case InstructionFail::SSSE3:
|
case InstructionFail::SSSE3:
|
||||||
return "SSSE3";
|
ret("SSSE3");
|
||||||
case InstructionFail::SSE4_1:
|
case InstructionFail::SSE4_1:
|
||||||
return "SSE4.1";
|
ret("SSE4.1");
|
||||||
case InstructionFail::SSE4_2:
|
case InstructionFail::SSE4_2:
|
||||||
return "SSE4.2";
|
ret("SSE4.2");
|
||||||
case InstructionFail::POPCNT:
|
case InstructionFail::POPCNT:
|
||||||
return "POPCNT";
|
ret("POPCNT");
|
||||||
case InstructionFail::AVX:
|
case InstructionFail::AVX:
|
||||||
return "AVX";
|
ret("AVX");
|
||||||
case InstructionFail::AVX2:
|
case InstructionFail::AVX2:
|
||||||
return "AVX2";
|
ret("AVX2");
|
||||||
case InstructionFail::AVX512:
|
case InstructionFail::AVX512:
|
||||||
return "AVX512";
|
ret("AVX512");
|
||||||
}
|
}
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
@ -242,9 +245,8 @@ void checkRequiredInstructionsImpl(volatile InstructionFail & fail)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This function is safe to use in static initializers.
|
/// This function is safe to use in static initializers.
|
||||||
void writeError(const char * data)
|
void writeErrorLen(const char * data, size_t size)
|
||||||
{
|
{
|
||||||
size_t size = strlen(data);
|
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
ssize_t res = ::write(STDERR_FILENO, data, size);
|
ssize_t res = ::write(STDERR_FILENO, data, size);
|
||||||
@ -259,6 +261,10 @@ void writeError(const char * data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Macros to avoid using strlen(), since it may fail if SSE is not supported.
|
||||||
|
#define writeError(data) \
|
||||||
|
static_assert(__builtin_constant_p(data)); \
|
||||||
|
writeErrorLen(data, ARRAY_SIZE(data) - 1)
|
||||||
|
|
||||||
/// Check SSE and others instructions availability. Calls exit on fail.
|
/// Check SSE and others instructions availability. Calls exit on fail.
|
||||||
/// This function must be called as early as possible, even before main, because static initializers may use unavailable instructions.
|
/// This function must be called as early as possible, even before main, because static initializers may use unavailable instructions.
|
||||||
@ -286,7 +292,7 @@ void checkRequiredInstructions()
|
|||||||
if (sigsetjmp(jmpbuf, 1))
|
if (sigsetjmp(jmpbuf, 1))
|
||||||
{
|
{
|
||||||
writeError("Instruction check fail. The CPU does not support ");
|
writeError("Instruction check fail. The CPU does not support ");
|
||||||
writeError(instructionFailToString(fail));
|
std::apply(writeErrorLen, instructionFailToString(fail));
|
||||||
writeError(" instruction set.\n");
|
writeError(" instruction set.\n");
|
||||||
_Exit(1);
|
_Exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user