Fixes and tweaks to the networking impl

This commit is contained in:
Wojtek Figat
2021-01-27 10:37:15 +01:00
parent a876e56339
commit cd2ae08da0
5 changed files with 87 additions and 88 deletions

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "NetworkBase.h"
@@ -101,4 +101,3 @@ NetworkEndPoint NetworkBase::RemapEndPointToIPv6(NetworkEndPoint& endPoint)
{
return NetworkEndPoint();
}

View File

@@ -5,20 +5,27 @@
#include "Engine/Core/Types/BaseTypes.h"
#include "Engine/Core/Types/String.h"
API_INJECT_CPP_CODE("#include \"Engine/Platform/Network.h\"");
#define SOCKGROUP_MAXCOUNT 64
#define SOCKGROUP_ITEMSIZE 16
enum class FLAXENGINE_API NetworkProtocolType
{
/// <summary>Not specified.</summary>
Undefined,
/// <summary>User Datagram Protocol.</summary>
Udp,
/// <summary>Transmission Control Protocol.</summary>
Tcp
};
enum class FLAXENGINE_API NetworkIPVersion
{
/// <summary>Not specified.</summary>
Undefined,
/// <summary>Internet Protocol version 4.</summary>
IPv4,
/// <summary>Internet Protocol version 6.</summary>
IPv6
};
@@ -26,7 +33,7 @@ struct FLAXENGINE_API NetworkSocket
{
NetworkProtocolType Protocol = NetworkProtocolType::Undefined;
NetworkIPVersion IPVersion = NetworkIPVersion::Undefined;
byte Data[8] = {}; // sizeof SOCKET = unsigned __int64
byte Data[8] = {};
};
struct FLAXENGINE_API NetworkEndPoint
@@ -34,26 +41,41 @@ struct FLAXENGINE_API NetworkEndPoint
NetworkIPVersion IPVersion = NetworkIPVersion::Undefined;
String Address;
String Port;
byte Data[28] = {}; // sizeof sockaddr_in6 , biggest sockaddr that we will use
byte Data[28] = {};
};
enum FLAXENGINE_API NetworkSocketOption
enum class FLAXENGINE_API NetworkSocketOption
{
/// <summary>Enables debugging info recording.</summary>
Debug,
/// <summary>Allows local address reusing.</summary>
ReuseAddr,
/// <summary>Keeps connections alive.</summary>
KeepAlive,
/// <summary>Indicates that outgoing data should be sent on whatever interface the socket is bound to and not a routed on some other interface.</summary>
DontRoute,
/// <summary>Allows for sending broadcast data.</summary>
Broadcast,
/// <summary>Uses the local loopback address when sending data from this socket.</summary>
UseLoopback,
/// <summary>Lingers on close if data present.</summary>
Linger,
/// <summary>Allows out-of-bound data to be returned in-line with regular data.</summary>
OOBInline,
/// <summary>Socket send data buffer size.</summary>
SendBuffer,
/// <summary>Socket receive data buffer size.</summary>
RecvBuffer,
/// <summary>The timeout in milliseconds for blocking send calls.</summary>
SendTimeout,
/// <summary>The timeout in milliseconds for blocking receive calls.</summary>
RecvTimeout,
/// <summary>The last socket error code.</summary>
Error,
/// <summary>Enables the Nagle algorithm for TCP sockets.</summary>
NoDelay,
IPv6Only
/// <summary>Enables IPv6 communication only for TCP socket.</summary>
IPv6Only,
};
struct FLAXENGINE_API NetworkSocketState
@@ -68,12 +90,12 @@ struct FLAXENGINE_API NetworkSocketState
struct FLAXENGINE_API NetworkSocketGroup
{
uint32 Count = 0;
byte Data[SOCKGROUP_MAXCOUNT * 16] = {};
byte Data[SOCKGROUP_MAXCOUNT * SOCKGROUP_ITEMSIZE] = {};
};
class FLAXENGINE_API NetworkBase
{
public:
public:
/// <summary>
/// Creates a new native socket.
/// </summary>
@@ -241,4 +263,3 @@ class FLAXENGINE_API NetworkBase
/// <returns>The ipv6 end point.</returns>
static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint);
};

View File

@@ -111,6 +111,7 @@ void UWPPlatform::BeforeExit()
void UWPPlatform::Exit()
{
Win32Platform::Exit();
}
int32 UWPPlatform::GetDpi()

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "Win32Network.h"
#include "Engine/Core/Log.h"
@@ -12,8 +12,10 @@
static_assert(sizeof NetworkSocket::Data >= sizeof SOCKET, "NetworkSocket::Data is not big enough to contains SOCKET !");
static_assert(sizeof NetworkEndPoint::Data >= sizeof sockaddr_in6, "NetworkEndPoint::Data is not big enough to contains sockaddr_in6 !");
// @formatter:off
static const IN6_ADDR v4MappedPrefix = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } };
// @formatter:on
/*
* Known issues :
@@ -24,9 +26,9 @@ static String GetErrorMessage(int error)
{
wchar_t* s = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
nullptr, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
String str(s);
LocalFree(s);
return str;
@@ -72,11 +74,11 @@ static bool CreateEndPointFromAddr(sockaddr* addr, NetworkEndPoint& endPoint)
LOG(Error, "Unable to create endpoint, sockaddr must be INET or INET6! Family : {0}", addr->sa_family);
return true;
}
char ip[INET6_ADDRSTRLEN];
if (inet_ntop(addr->sa_family, paddr, ip, INET6_ADDRSTRLEN) == nullptr)
{
LOG(Error, "Unable to extract address from sockaddr! Error : {0}", GetLastErrorMessage().Get());
LOG(Error, "Unable to extract address from sockaddr! Error : {0}", GetLastErrorMessage());
return true;
}
endPoint.Address = String(ip);
@@ -107,7 +109,7 @@ static void PrintAddrFromInfo(addrinfoW& info)
char str[INET6_ADDRSTRLEN];
inet_ntop(curr->ai_family, addr, str, INET6_ADDRSTRLEN);
LOG(Info, "ADDR INFO family : {0} socktype : {1}, proto : {2} address : {3}", curr->ai_family, curr->ai_socktype, curr->ai_protocol, StringAnsi(str).ToString().Get());
LOG(Info, "ADDR INFO family : {0} socktype : {1}, proto : {2} address : {3}", curr->ai_family, curr->ai_socktype, curr->ai_protocol, StringAnsi(str).ToString());
}
}
@@ -115,21 +117,21 @@ static void TranslateSockOptToNative(NetworkSocketOption option, int32* level, i
{
switch (option)
{
SOCKOPT(NetworkSocketOption::Debug, SOL_SOCKET, SO_DEBUG)
SOCKOPT(NetworkSocketOption::ReuseAddr, SOL_SOCKET, SO_REUSEADDR)
SOCKOPT(NetworkSocketOption::KeepAlive, SOL_SOCKET, SO_KEEPALIVE)
SOCKOPT(NetworkSocketOption::DontRoute, SOL_SOCKET, SO_DONTROUTE)
SOCKOPT(NetworkSocketOption::Broadcast, SOL_SOCKET, SO_BROADCAST)
SOCKOPT(NetworkSocketOption::UseLoopback, SOL_SOCKET, SO_USELOOPBACK)
SOCKOPT(NetworkSocketOption::Linger, SOL_SOCKET, SO_LINGER)
SOCKOPT(NetworkSocketOption::OOBInline, SOL_SOCKET, SO_OOBINLINE)
SOCKOPT(NetworkSocketOption::SendBuffer, SOL_SOCKET, SO_SNDBUF)
SOCKOPT(NetworkSocketOption::RecvBuffer, SOL_SOCKET, SO_RCVBUF)
SOCKOPT(NetworkSocketOption::SendTimeout, SOL_SOCKET, SO_SNDTIMEO)
SOCKOPT(NetworkSocketOption::RecvTimeout, SOL_SOCKET, SO_RCVTIMEO)
SOCKOPT(NetworkSocketOption::Error, SOL_SOCKET, SO_ERROR)
SOCKOPT(NetworkSocketOption::NoDelay, IPPROTO_TCP, TCP_NODELAY)
SOCKOPT(NetworkSocketOption::IPv6Only, IPPROTO_IPV6, IPV6_V6ONLY)
SOCKOPT(NetworkSocketOption::Debug, SOL_SOCKET, SO_DEBUG)
SOCKOPT(NetworkSocketOption::ReuseAddr, SOL_SOCKET, SO_REUSEADDR)
SOCKOPT(NetworkSocketOption::KeepAlive, SOL_SOCKET, SO_KEEPALIVE)
SOCKOPT(NetworkSocketOption::DontRoute, SOL_SOCKET, SO_DONTROUTE)
SOCKOPT(NetworkSocketOption::Broadcast, SOL_SOCKET, SO_BROADCAST)
SOCKOPT(NetworkSocketOption::UseLoopback, SOL_SOCKET, SO_USELOOPBACK)
SOCKOPT(NetworkSocketOption::Linger, SOL_SOCKET, SO_LINGER)
SOCKOPT(NetworkSocketOption::OOBInline, SOL_SOCKET, SO_OOBINLINE)
SOCKOPT(NetworkSocketOption::SendBuffer, SOL_SOCKET, SO_SNDBUF)
SOCKOPT(NetworkSocketOption::RecvBuffer, SOL_SOCKET, SO_RCVBUF)
SOCKOPT(NetworkSocketOption::SendTimeout, SOL_SOCKET, SO_SNDTIMEO)
SOCKOPT(NetworkSocketOption::RecvTimeout, SOL_SOCKET, SO_RCVTIMEO)
SOCKOPT(NetworkSocketOption::Error, SOL_SOCKET, SO_ERROR)
SOCKOPT(NetworkSocketOption::NoDelay, IPPROTO_TCP, TCP_NODELAY)
SOCKOPT(NetworkSocketOption::IPv6Only, IPPROTO_IPV6, IPV6_V6ONLY)
}
}
@@ -144,14 +146,14 @@ bool Win32Network::CreateSocket(NetworkSocket& socket, NetworkProtocolType proto
if ((sock = ::socket(family, stype, prot)) == INVALID_SOCKET)
{
LOG(Error, "Can't create native socket! Error : {0}", GetLastErrorMessage().Get());
LOG(Error, "Can't create native socket! Error : {0}", GetLastErrorMessage());
return true;
}
memcpy(socket.Data, &sock, sizeof sock);
unsigned long value = 1;
if (ioctlsocket(sock, FIONBIO, &value) == SOCKET_ERROR)
{
LOG(Error, "Can't set socket to NON-BLOCKING type! Error : {0}", GetLastErrorMessage().Get());
LOG(Error, "Can't set socket to NON-BLOCKING type! Error : {0}", GetLastErrorMessage());
return true; // Support using blocking socket , need to test it
}
return false;
@@ -181,10 +183,10 @@ bool Win32Network::SetSocketOption(NetworkSocket& socket, NetworkSocketOption op
int32 optnme = 0;
TranslateSockOptToNative(option, &optlvl, &optnme);
if (setsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)&value, sizeof value) == SOCKET_ERROR)
{
LOG(Warning, "Unable to set socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage().Get());
LOG(Warning, "Unable to set socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage());
return true;
}
return false;
@@ -202,13 +204,13 @@ bool Win32Network::GetSocketOption(NetworkSocket& socket, NetworkSocketOption op
{
int32 optlvl = 0;
int32 optnme = 0;
TranslateSockOptToNative(option, &optlvl, &optnme);
int32 size;
if (getsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)value, &size) == SOCKET_ERROR)
{
LOG(Warning, "Unable to get socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage().Get());
LOG(Warning, "Unable to get socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage());
return true;
}
return false;
@@ -222,7 +224,7 @@ bool Win32Network::ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoin
int error = WSAGetLastError();
if (error == WSAEWOULDBLOCK)
return false;
LOG(Error, "Unable to connect socket to address! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address.Get(), endPoint.Port.Get(), GetErrorMessage(error).Get());
LOG(Error, "Unable to connect socket to address! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address, endPoint.Port, GetErrorMessage(error));
return true;
}
return false;
@@ -239,7 +241,7 @@ bool Win32Network::BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint)
const uint16 size = endPoint.IPVersion == NetworkIPVersion::IPv6 ? sizeof sockaddr_in6 : sizeof sockaddr_in;
if (bind(*(SOCKET*)socket.Data, (const sockaddr*)endPoint.Data, size) == SOCKET_ERROR)
{
LOG(Error, "Unable to bind socket! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address.Get(), endPoint.Port.Get(), GetLastErrorMessage().Get());
LOG(Error, "Unable to bind socket! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address, endPoint.Port, GetLastErrorMessage());
return true;
}
return false;
@@ -249,7 +251,7 @@ bool Win32Network::Listen(NetworkSocket& socket, uint16 queueSize)
{
if (listen(*(SOCKET*)socket.Data, (int32)queueSize) == SOCKET_ERROR)
{
LOG(Error, "Unable to listen ! Socket : {0} Error : {1}", GetLastErrorMessage().Get());
LOG(Error, "Unable to listen ! Socket : {0} Error : {1}", GetLastErrorMessage());
return true;
}
return false;
@@ -270,7 +272,7 @@ bool Win32Network::Accept(NetworkSocket& serverSock, NetworkSocket& newSock, Net
int32 error = WSAGetLastError();
if (error == WSAEWOULDBLOCK)
return false;
LOG(Warning, "Unable to accept incoming connection! Socket : {0} Error : {1}", *(SOCKET*)serverSock.Data, GetErrorMessage(error).Get());
LOG(Warning, "Unable to accept incoming connection! Socket : {0} Error : {1}", *(SOCKET*)serverSock.Data, GetErrorMessage(error));
return true;
}
memcpy(newSock.Data, &sock, sizeof sock);
@@ -292,7 +294,7 @@ bool Win32Network::IsReadable(NetworkSocket& socket)
int32 error = WSAGetLastError();
if (error == WSAEWOULDBLOCK)
return false;
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error).Get());
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error));
return false;
}
if (entry.revents & POLLRDNORM)
@@ -310,7 +312,7 @@ bool Win32Network::IsWriteable(NetworkSocket& socket)
int32 error = WSAGetLastError();
if (error == WSAEWOULDBLOCK)
return false;
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error).Get());
LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error));
return false;
}
if (entry.revents & POLLWRNORM)
@@ -322,7 +324,7 @@ int32 Win32Network::Poll(NetworkSocketGroup& group)
{
int32 pollret = WSAPoll((pollfd*)group.Data, group.Count, 0);
if (pollret == SOCKET_ERROR)
LOG(Error, "Unable to poll socket group! Error : {0}", GetLastErrorMessage().Get());
LOG(Error, "Unable to poll socket group! Error : {0}", GetLastErrorMessage());
return pollret;
}
@@ -354,7 +356,7 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s
pollinfo.events = POLLRDNORM | POLLWRNORM;
*(pollfd*)&group.Data[group.Count * SOCKGROUP_ITEMSIZE] = pollinfo;
group.Count++;
return group.Count-1;
return group.Count - 1;
}
void Win32Network::ClearGroup(NetworkSocketGroup& group)
@@ -374,7 +376,7 @@ int32 Win32Network::WriteSocket(NetworkSocket socket, byte* data, uint32 length,
{
if ((size = send(*(SOCKET*)socket.Data, (const char*)data, length, 0)) == SOCKET_ERROR)
{
LOG(Error, "Unable to send data! Socket : {0} Data Length : {1} Error : {2}", *(SOCKET*)socket.Data, length, GetLastErrorMessage().Get());
LOG(Error, "Unable to send data! Socket : {0} Data Length : {1} Error : {2}", *(SOCKET*)socket.Data, length, GetLastErrorMessage());
return -1;
}
}
@@ -382,13 +384,13 @@ int32 Win32Network::WriteSocket(NetworkSocket socket, byte* data, uint32 length,
{
if ((size = sendto(*(SOCKET*)socket.Data, (const char*)data, length, 0, (const sockaddr*)endPoint->Data, GetAddrSizeFromEP(*endPoint))) == SOCKET_ERROR)
{
LOG(Error, "Unable to send data! Socket : {0} Address : {1} Port : {2} Data Length : {3} Error : {4}", *(SOCKET*)socket.Data, endPoint->Address, endPoint->Port, length, GetLastErrorMessage().Get());
LOG(Error, "Unable to send data! Socket : {0} Address : {1} Port : {2} Data Length : {3} Error : {4}", *(SOCKET*)socket.Data, endPoint->Address, endPoint->Port, length, GetLastErrorMessage());
return -1;
}
}
else
{
//TODO: better explanation
// TODO: better explanation
LOG(Error, "Unable to send data! Socket : {0} Data Length : {1}", *(SOCKET*)socket.Data, length);
return -1;
}
@@ -405,7 +407,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer
const int32 error = WSAGetLastError();
if (error == WSAEWOULDBLOCK)
return 0;
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetErrorMessage(error).Get());
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetErrorMessage(error));
return -1;
}
}
@@ -415,7 +417,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer
sockaddr_in6 addr;
if ((size = recvfrom(*(SOCKET*)socket.Data, (char*)buffer, bufferSize, 0, (sockaddr*)&addr, &addrsize)) == SOCKET_ERROR)
{
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetLastErrorMessage().Get());
LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetLastErrorMessage());
return -1;
}
if (CreateEndPointFromAddr((sockaddr*)&addr, *endPoint))
@@ -439,13 +441,13 @@ bool Win32Network::CreateEndPoint(String* address, String* port, NetworkIPVersio
// consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names )
if ((status = GetAddrInfoW(address == nullptr ? nullptr : address->Get(), port->Get(), &hints, &info)) != 0)
{
LOG(Error, "Unable to query info for address : {0} Error : {1}", address != nullptr ? address->Get() : String("ANY").Get(), gai_strerror(status));
LOG(Error, "Unable to query info for address : {0} Error : {1}", address ? address->Get() : String("ANY"), gai_strerror(status));
return true;
}
if (info == nullptr)
{
LOG(Error, "Unable to resolve address! Address : {0}", address != nullptr ? address->Get() : String("ANY").Get());
LOG(Error, "Unable to resolve address! Address : {0}", address ? address->Get() : String("ANY"));
return true;
}

View File

@@ -9,10 +9,9 @@
#include "Engine/Core/Types/Guid.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Math/Math.h"
#include "IncludeWindowsHeaders.h"
#include "Engine/Core/Collections/HashFunctions.h"
#include "Engine/Platform/Network.h"
#include "Engine/Core/Log.h"
#include "IncludeWindowsHeaders.h"
#include <Psapi.h>
#include <WinSock2.h>
@@ -27,10 +26,9 @@ namespace
CPUInfo CpuInfo;
uint64 ClockFrequency;
double CyclesToSeconds;
WSAData WsaData;
}
static WSAData _wsaData;
// Helper function to count set bits in the processor mask
DWORD CountSetBits(ULONG_PTR bitMask)
{
@@ -52,9 +50,9 @@ static String GetLastErrorMessage()
{
wchar_t* s = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
nullptr, WSAGetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPWSTR>(&s), 0, nullptr);
String str(s);
LocalFree(s);
return str;
@@ -72,6 +70,7 @@ bool Win32Platform::Init()
ClockFrequency = frequency.QuadPart;
CyclesToSeconds = 1.0 / static_cast<double>(frequency.QuadPart);
// Count CPUs
BOOL done = FALSE;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = nullptr;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr;
@@ -84,12 +83,10 @@ bool Win32Platform::Init()
DWORD processorPackageCount = 0;
DWORD byteOffset = 0;
PCACHE_DESCRIPTOR cache;
while (!done)
{
DWORD rc = GetLogicalProcessorInformation(buffer, &returnLength);
if (FALSE == rc)
if (rc == FALSE)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
@@ -97,9 +94,7 @@ bool Win32Platform::Init()
{
free(buffer);
}
buffer = static_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION>(malloc(returnLength));
if (buffer == nullptr)
{
return true;
@@ -115,23 +110,16 @@ bool Win32Platform::Init()
done = TRUE;
}
}
ptr = buffer;
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)
{
switch (ptr->Relationship)
{
case RelationProcessorCore:
processorCoreCount++;
// A hyper threaded core supplies more than one logical processor
logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
break;
case RelationCache:
// Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
cache = &ptr->Cache;
if (cache->Level == 1)
{
@@ -146,9 +134,7 @@ bool Win32Platform::Init()
processorL3CacheSize += cache->Size;
}
break;
case RelationProcessorPackage:
// Logical processors share a physical package
processorPackageCount++;
break;
}
@@ -228,8 +214,10 @@ bool Win32Platform::Init()
DeviceId.D = (uint32)cpuInfo.ClockSpeed * cpuInfo.LogicalProcessorCount * cpuInfo.ProcessorCoreCount * cpuInfo.CacheLineSize;
}
if (WSAStartup(MAKEWORD(2, 0), &_wsaData) != 0)
LOG(Error, "Unable to initializes native network! Error : {0}", GetLastErrorMessage().Get());
// Init networking
if (WSAStartup(MAKEWORD(2, 0), &WsaData) != 0)
LOG(Error, "Unable to initializes native network! Error : {0}", GetLastErrorMessage());
return false;
}
@@ -240,19 +228,8 @@ void Win32Platform::Exit()
void Win32Platform::MemoryBarrier()
{
// NOTE: _ReadWriteBarrier and friends only prevent the
// compiler from reordering loads and stores. To prevent
// the CPU from doing the same, we have to use the
// MemoryBarrier macro which expands to e.g. a serializing
// XCHG instruction on x86. Also note that the MemoryBarrier
// macro does *not* imply _ReadWriteBarrier, so that call
// cannot be eliminated.
_ReadWriteBarrier();
// MemoryBarrier macro (we use undef to hide some symbols from Windows headers)
#if PLATFORM_64BITS
#ifdef _AMD64_
__faststorefence();
#elif defined(_IA64_)
@@ -260,7 +237,6 @@ void Win32Platform::MemoryBarrier()
#else
#error "Invalid platform."
#endif
#else
LONG barrier;
__asm {