Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recheck some conditional compile #31

Merged
merged 5 commits into from
Dec 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/DotNetty.Buffers/ByteBufferUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,20 +212,33 @@ public static unsafe float Int32BitsToSingle(int value)
/// Toggles the endianness of the specified 64-bit long integer.
/// </summary>
public static long SwapLong(long value)
#if !NETFRAMEWORK
=> System.Buffers.Binary.BinaryPrimitives.ReverseEndianness(value);
#else
=> ((SwapInt((int)value) & 0xFFFFFFFF) << 32)
| (SwapInt((int)(value >> 32)) & 0xFFFFFFFF);
#endif

/// <summary>
/// Toggles the endianness of the specified 32-bit integer.
/// </summary>
public static int SwapInt(int value)
#if !NETFRAMEWORK
=> System.Buffers.Binary.BinaryPrimitives.ReverseEndianness(value);
#else
=> ((SwapShort((short)value) & 0xFFFF) << 16)
| (SwapShort((short)(value >> 16)) & 0xFFFF);
#endif

/// <summary>
/// Toggles the endianness of the specified 16-bit integer.
/// </summary>
public static short SwapShort(short value) => (short)(((value & 0xFF) << 8) | (value >> 8) & 0xFF);
public static short SwapShort(short value)
#if !NETFRAMEWORK
=> System.Buffers.Binary.BinaryPrimitives.ReverseEndianness(value);
#else
=> (short)(((value & 0xFF) << 8) | (value >> 8) & 0xFF);
#endif

}
}
66 changes: 59 additions & 7 deletions src/DotNetty.Buffers/HeapByteBufferUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

namespace DotNetty.Buffers
{
#if !NETFRAMEWORK
using System;
using System.Buffers.Binary;
#endif
using System.Runtime.CompilerServices;

static class HeapByteBufferUtil
Expand All @@ -33,15 +37,23 @@ static class HeapByteBufferUtil
internal static byte GetByte(byte[] memory, int index) => memory[index];

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static short GetShort(byte[] memory, int index) =>
internal static short GetShort(byte[] memory, int index) =>
#if !NETFRAMEWORK
BinaryPrimitives.ReadInt16BigEndian(memory.AsSpan(index));
#else
unchecked((short)(memory[index] << 8 | memory[index + 1]));
#endif

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static short GetShortLE(byte[] memory, int index) =>
internal static short GetShortLE(byte[] memory, int index) =>
#if !NETFRAMEWORK
BinaryPrimitives.ReadInt16LittleEndian(memory.AsSpan(index));
#else
unchecked((short)(memory[index] | memory[index + 1] << 8));
#endif

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static int GetUnsignedMedium(byte[] memory, int index) =>
internal static int GetUnsignedMedium(byte[] memory, int index) =>
unchecked(
memory[index] << 16 |
memory[index + 1] << 8 |
Expand All @@ -55,23 +67,34 @@ internal static int GetUnsignedMediumLE(byte[] memory, int index) =>
memory[index + 2] << 16);

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static int GetInt(byte[] memory, int index) =>
internal static int GetInt(byte[] memory, int index) =>
#if !NETFRAMEWORK
BinaryPrimitives.ReadInt32BigEndian(memory.AsSpan(index));
#else
unchecked(
memory[index] << 24 |
memory[index + 1] << 16 |
memory[index + 2] << 8 |
memory[index + 3]);
#endif

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static int GetIntLE(byte[] memory, int index) =>
internal static int GetIntLE(byte[] memory, int index) =>
#if !NETFRAMEWORK
BinaryPrimitives.ReadInt32LittleEndian(memory.AsSpan(index));
#else
unchecked(
memory[index] |
memory[index + 1] << 8 |
memory[index + 2] << 16 |
memory[index + 3] << 24);
#endif

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static long GetLong(byte[] memory, int index) =>
internal static long GetLong(byte[] memory, int index) =>
#if !NETFRAMEWORK
BinaryPrimitives.ReadInt64BigEndian(memory.AsSpan(index));
#else
unchecked(
(long)memory[index] << 56 |
(long)memory[index + 1] << 48 |
Expand All @@ -81,9 +104,13 @@ internal static long GetLong(byte[] memory, int index) =>
(long)memory[index + 5] << 16 |
(long)memory[index + 6] << 8 |
memory[index + 7]);
#endif

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static long GetLongLE(byte[] memory, int index) =>
internal static long GetLongLE(byte[] memory, int index) =>
#if !NETFRAMEWORK
BinaryPrimitives.ReadInt64LittleEndian(memory.AsSpan(index));
#else
unchecked(
memory[index] |
(long)memory[index + 1] << 8 |
Expand All @@ -93,6 +120,7 @@ internal static long GetLongLE(byte[] memory, int index) =>
(long)memory[index + 5] << 40 |
(long)memory[index + 6] << 48 |
(long)memory[index + 7] << 56);
#endif

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetByte(byte[] memory, int index, int value)
Expand All @@ -106,21 +134,29 @@ internal static void SetByte(byte[] memory, int index, int value)
[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetShort(byte[] memory, int index, int value)
{
#if !NETFRAMEWORK
BinaryPrimitives.WriteInt16BigEndian(memory.AsSpan(index), unchecked((short)value));
#else
unchecked
{
memory[index] = (byte)((ushort)value >> 8);
memory[index + 1] = (byte)value;
}
#endif
}

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetShortLE(byte[] memory, int index, int value)
{
#if !NETFRAMEWORK
BinaryPrimitives.WriteInt16LittleEndian(memory.AsSpan(index), unchecked((short)value));
#else
unchecked
{
memory[index] = (byte)value;
memory[index + 1] = (byte)((ushort)value >> 8);
}
#endif
}

[MethodImpl(InlineMethod.AggressiveInlining)]
Expand Down Expand Up @@ -150,6 +186,9 @@ internal static void SetMediumLE(byte[] memory, int index, int value)
[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetInt(byte[] memory, int index, int value)
{
#if !NETFRAMEWORK
BinaryPrimitives.WriteInt32BigEndian(memory.AsSpan(index), value);
#else
unchecked
{
uint unsignedValue = (uint)value;
Expand All @@ -158,11 +197,15 @@ internal static void SetInt(byte[] memory, int index, int value)
memory[index + 2] = (byte)(unsignedValue >>8);
memory[index + 3] = (byte)unsignedValue;
}
#endif
}

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetIntLE(byte[] memory, int index, int value)
{
#if !NETFRAMEWORK
BinaryPrimitives.WriteInt32LittleEndian(memory.AsSpan(index), value);
#else
unchecked
{
uint unsignedValue = (uint)value;
Expand All @@ -171,11 +214,15 @@ internal static void SetIntLE(byte[] memory, int index, int value)
memory[index + 2] = (byte)(unsignedValue >> 16);
memory[index + 3] = (byte)(unsignedValue >> 24);
}
#endif
}

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetLong(byte[] memory, int index, long value)
{
#if !NETFRAMEWORK
BinaryPrimitives.WriteInt64BigEndian(memory.AsSpan(index), value);
#else
unchecked
{
ulong unsignedValue = (ulong)value;
Expand All @@ -188,11 +235,15 @@ internal static void SetLong(byte[] memory, int index, long value)
memory[index + 6] = (byte)(unsignedValue >> 8);
memory[index + 7] = (byte)unsignedValue;
}
#endif
}

[MethodImpl(InlineMethod.AggressiveInlining)]
internal static void SetLongLE(byte[] memory, int index, long value)
{
#if !NETFRAMEWORK
BinaryPrimitives.WriteInt64LittleEndian(memory.AsSpan(index), value);
#else
unchecked
{
ulong unsignedValue = (ulong)value;
Expand All @@ -205,6 +256,7 @@ internal static void SetLongLE(byte[] memory, int index, long value)
memory[index + 6] = (byte)(unsignedValue >> 48);
memory[index + 7] = (byte)(unsignedValue >> 56);
}
#endif
}
}
}
37 changes: 20 additions & 17 deletions src/DotNetty.Common/Concurrency/XThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,31 @@ public void Start()

void CreateLongRunningTask(XParameterizedThreadStart threadStartFunc)
{
_task = Task.Factory.StartNew(
() =>
{
using (ExecutionContext.IsFlowSuppressed() ? default(AsyncFlowControl?) : ExecutionContext.SuppressFlow())
{
_task = Task.Factory.StartNew(
() =>
{
// We start the task running, then unleash it by signaling the readyToStart event.
// This is needed to avoid thread reuse for tasks (see below)
_ = _readyToStart.WaitOne();
// This is the first time we're using this thread, therefore the TLS slot must be empty
if (s_currentThread is object)
{
Debug.WriteLine("warning: currentThread already created; OS thread reused");
Debug.Assert(false);
}
s_currentThread = this;
threadStartFunc(_startupParameter);
_ = _completed.Set();
},
CancellationToken.None,
// .NET always creates a brand new thread for LongRunning tasks
// This is not documented but unlikely to ever change:
// https://github.com/dotnet/corefx/issues/2576#issuecomment-126693306
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
{
Debug.WriteLine("warning: currentThread already created; OS thread reused");
Debug.Assert(false);
}
s_currentThread = this;
threadStartFunc(_startupParameter);
_ = _completed.Set();
},
CancellationToken.None,
// .NET always creates a brand new thread for LongRunning tasks
// This is not documented but unlikely to ever change:
// https://github.com/dotnet/corefx/issues/2576#issuecomment-126693306
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}
}

public void Start(object parameter)
Expand Down
48 changes: 27 additions & 21 deletions src/DotNetty.Common/Internal/TextEncodings.Utf16.NetCore2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,31 +122,37 @@ public unsafe static OperationStatus ToUtf8(ref byte utf16Source, int utf16Lengt
}

// Unfortunately, this is endianess sensitive
#if BIGENDIAN
*pTarget = (byte)(ch >> 16);
*(pTarget + 1) = (byte)ch;
pSrc += 4;
*(pTarget + 2) = (byte)(chc >> 16);
*(pTarget + 3) = (byte)chc;
pTarget += 4;
#else // BIGENDIAN
*pTarget = (byte)ch;
*(pTarget + 1) = (byte)(ch >> 16);
pSrc += 4;
*(pTarget + 2) = (byte)chc;
*(pTarget + 3) = (byte)(chc >> 16);
pTarget += 4;
#endif // BIGENDIAN
if (!BitConverter.IsLittleEndian)
{
*pTarget = (byte)(ch >> 16);
*(pTarget + 1) = (byte)ch;
pSrc += 4;
*(pTarget + 2) = (byte)(chc >> 16);
*(pTarget + 3) = (byte)chc;
pTarget += 4;
}
else
{
*pTarget = (byte)ch;
*(pTarget + 1) = (byte)(ch >> 16);
pSrc += 4;
*(pTarget + 2) = (byte)chc;
*(pTarget + 3) = (byte)(chc >> 16);
pTarget += 4;
}
}
continue;

LongCodeWithMask:
#if BIGENDIAN
// be careful about the sign extension
ch = (int)(((uint)ch) >> 16);
#else // BIGENDIAN
ch = (char)ch;
#endif // BIGENDIAN
if (!BitConverter.IsLittleEndian)
{
// be careful about the sign extension
ch = (int)(((uint)ch) >> 16);
}
else
{
ch = (char)ch;
}
pSrc++;

if (ch > 0x7F)
Expand Down
Loading