From 45d2d36c9dbcbce403c78838ea52acd1ab111b68 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Dec 2010 19:52:48 +0100 Subject: Add an SSE4.2 even simpler version of toLatin1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new PCMPESTRM instruction (Parallel CoMPare Explicit-length STRings with result in a Mask) which is added in SSE4.2 for facilitating string operations. The "compare ranges" mode allows us to search for characters outside the Latin 1 range and then use the SSE4.1 PBLENDVB instruction to replace those with question marks. Unlike previous SSE compare instructions, the PCMPxSTRx family allows us to operate on unsigned 16-bit values. This saves us another parallel add. Reviewed-By: Samuel Rødal --- src/corelib/tools/qstring.cpp | 23 +++++++++++++++++++++++ tests/auto/qstring/tst_qstring.cpp | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 0edf29150e..0828ccb49a 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3561,6 +3561,28 @@ static inline __m128i mergeQuestionMarks(__m128i chunk) { const __m128i questionMark = _mm_set1_epi16('?'); +# ifdef __SSE4_2__ + // compare the unsigned shorts for the range 0x0100-0xFFFF + // note on the use of _mm_cmpestrm: + // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx) + // says for range search the following: + // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3 + // + // However, all examples on the Internet, including from Intel + // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/) + // put the range to be searched first + // + // Disassembly and instruction-level debugging with GCC and ICC show + // that they are doing the right thing. Inverting the arguments in the + // instruction does cause a bunch of test failures. + + const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK; + const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100); + const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode); + + // replace the non-Latin 1 characters in the chunk with question marks + chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask); +# else // SSE has no compare instruction for unsigned comparison. // The variables must be shiffted + 0x8000 to be compared const __m128i signedBitOffset = _mm_set1_epi16(0x8000); @@ -3584,6 +3606,7 @@ static inline __m128i mergeQuestionMarks(__m128i chunk) // merge offLimitQuestionMark and correctBytes to have the result chunk = _mm_or_si128(correctBytes, offLimitQuestionMark); # endif +# endif return chunk; } #endif diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index c19b168e9e..b26121c9d2 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -3475,6 +3475,10 @@ void tst_QString::toLatin1Roundtrip_data() static const ushort unicode6[] = { 0x180, 0x1ff, 0x8001, 0x8080, 0xfffc }; QTest::newRow("non-latin1b") << QByteArray("?????") << QString::fromUtf16(unicode6, 5) << questionmarks; + + static const ushort unicode7[] = { 'H', 'e', 'l', 'l', 'o', 0x100, 0x17f, 0x180, 0x8080, 0xfffc }; + static const ushort unicode7q[] = { 'H', 'e', 'l', 'l', 'o', '?', '?', '?', '?', '?' }; + QTest::newRow("mixed") << QByteArray("Hello?????") << QString::fromUtf16(unicode7, 10) << QString::fromUtf16(unicode7q, 10); } void tst_QString::toLatin1Roundtrip() -- cgit v1.2.3 From 59bd3bcd961fb3198dc9ba24996f7f9af67aeda3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jun 2011 21:14:01 +0200 Subject: Add a function that returns the D-Bus local machine ID Reviewed-by: Lars Knoll --- src/dbus/qdbus_symbols_p.h | 2 ++ src/dbus/qdbusconnection.cpp | 21 +++++++++++++++++++++ src/dbus/qdbusconnection.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index 8b46e6ac89..a59c08a8ab 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -301,6 +301,8 @@ DEFINEFUNC(void , dbus_get_version , (int *major_version_p, int *minor_version_p, int *micro_version_p), (major_version_p, minor_version_p, micro_version_p), ) +DEFINEFUNC(char* , dbus_get_local_machine_id , (void), (), return) + /* dbus-pending-call.h */ DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending, diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 6628ca3645..94989f550b 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -1122,6 +1122,27 @@ void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection) Qt::QueuedConnection); } +/*! + \since 4.8 + Returns the local machine ID as known to the D-Bus system. Each + node or host that runs D-Bus has a unique identifier that can be + used to distinguish it from other hosts if they are sharing + resources like the filesystem. + + Note that the local machine ID is not guaranteed to be persistent + across boots of the system, so this identifier should not be + stored in persistent storage (like the filesystem). It is + guaranteed to remain constant only during the lifetime of this + boot session. +*/ +QByteArray QDBusConnection::localMachineId() +{ + char *dbus_machine_id = q_dbus_get_local_machine_id(); + QByteArray result = dbus_machine_id; + q_dbus_free(dbus_machine_id); + return result; +} + /*! \namespace QDBus \inmodule QtDBus diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index 19418d61a6..4bdd055f52 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -176,6 +176,8 @@ public: static void disconnectFromBus(const QString &name); static void disconnectFromPeer(const QString &name); + static QByteArray localMachineId(); + static QDBusConnection sessionBus(); static QDBusConnection systemBus(); -- cgit v1.2.3