proper nextdouble
direct randombool thread safe parallelized timer changes
This commit is contained in:
parent
41019b691b
commit
b3831721d9
3 changed files with 163 additions and 84 deletions
123
Server/Random.cs
123
Server/Random.cs
|
|
@ -46,23 +46,28 @@ namespace Server {
|
|||
get { return _Random.GetType(); }
|
||||
}
|
||||
|
||||
public static double NextDouble() {
|
||||
return _Random.NextDouble();
|
||||
}
|
||||
|
||||
public static int Next(int c) {
|
||||
return _Random.Next(c);
|
||||
}
|
||||
|
||||
public static bool NextBool() {
|
||||
return _Random.NextBool();
|
||||
}
|
||||
|
||||
public static void NextBytes(byte[] b) {
|
||||
_Random.NextBytes(b);
|
||||
}
|
||||
|
||||
public static double NextDouble() {
|
||||
return _Random.NextDouble();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IRandomImpl {
|
||||
double NextDouble();
|
||||
int Next(int c);
|
||||
bool NextBool();
|
||||
void NextBytes(byte[] b);
|
||||
double NextDouble();
|
||||
}
|
||||
|
||||
public interface IHardwareRNG {
|
||||
|
|
@ -75,13 +80,6 @@ namespace Server {
|
|||
public SimpleRandom() {
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
double r;
|
||||
lock (m_Random)
|
||||
r = m_Random.NextDouble();
|
||||
return r;
|
||||
}
|
||||
|
||||
public int Next(int c) {
|
||||
int r;
|
||||
lock (m_Random)
|
||||
|
|
@ -89,10 +87,21 @@ namespace Server {
|
|||
return r;
|
||||
}
|
||||
|
||||
public bool NextBool() {
|
||||
return NextDouble() >= .5;
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b) {
|
||||
lock (m_Random)
|
||||
m_Random.NextBytes(b);
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
double r;
|
||||
lock (m_Random)
|
||||
r = m_Random.NextDouble();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CSPRandom : IRandomImpl {
|
||||
|
|
@ -145,18 +154,21 @@ namespace Server {
|
|||
}
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
byte[] b = new byte[8];
|
||||
|
||||
_GetBytes(b);
|
||||
|
||||
return (double)BitConverter.ToUInt64(b, 0) / ulong.MaxValue;
|
||||
}
|
||||
|
||||
public int Next(int c) {
|
||||
return (int)(c * NextDouble());
|
||||
}
|
||||
|
||||
public bool NextBool() {
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
private byte NextByte() {
|
||||
CheckSwap(1);
|
||||
|
||||
lock(_sync)
|
||||
return _Working[_Index++];
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b) {
|
||||
int c = b.Length;
|
||||
|
||||
|
|
@ -167,6 +179,19 @@ namespace Server {
|
|||
}
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
byte[] b = new byte[8];
|
||||
|
||||
_GetBytes(b);
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return ((double)(BitConverter.ToUInt64(b, 0) >> 11) / 9007199254740992);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RDRand32 : IRandomImpl, IHardwareRNG {
|
||||
|
|
@ -227,16 +252,21 @@ namespace Server {
|
|||
}
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
byte[] b = new byte[8];
|
||||
_GetBytes(b);
|
||||
return (double)BitConverter.ToUInt64(b, 0) / ulong.MaxValue;
|
||||
}
|
||||
|
||||
public int Next(int c) {
|
||||
return (int)(c * NextDouble());
|
||||
}
|
||||
|
||||
public bool NextBool() {
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
private byte NextByte() {
|
||||
CheckSwap(1);
|
||||
|
||||
lock(_sync)
|
||||
return _Working[_Index++];
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b) {
|
||||
int c = b.Length;
|
||||
|
||||
|
|
@ -246,6 +276,18 @@ namespace Server {
|
|||
}
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
byte[] b = new byte[8];
|
||||
_GetBytes(b);
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return ((double)(BitConverter.ToUInt64(b, 0) >> 11) / 9007199254740992);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RDRand64 : IRandomImpl, IHardwareRNG {
|
||||
|
|
@ -306,16 +348,21 @@ namespace Server {
|
|||
}
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
byte[] b = new byte[8];
|
||||
_GetBytes(b);
|
||||
return (double)BitConverter.ToUInt64(b, 0) / ulong.MaxValue;
|
||||
}
|
||||
|
||||
public int Next(int c) {
|
||||
return (int)(c * NextDouble());
|
||||
}
|
||||
|
||||
public bool NextBool() {
|
||||
return (NextByte() & 1) == 1;
|
||||
}
|
||||
|
||||
private byte NextByte() {
|
||||
CheckSwap(1);
|
||||
|
||||
lock(_sync)
|
||||
return _Working[_Index++];
|
||||
}
|
||||
|
||||
public void NextBytes(byte[] b) {
|
||||
int c = b.Length;
|
||||
|
||||
|
|
@ -325,6 +372,18 @@ namespace Server {
|
|||
}
|
||||
_GetBytes(b);
|
||||
}
|
||||
|
||||
public double NextDouble() {
|
||||
byte[] b = new byte[8];
|
||||
_GetBytes(b);
|
||||
|
||||
/* double: 53 bits of significand precision
|
||||
* ulong.MaxValue >> 11 = 9007199254740991
|
||||
* 2^53 = 9007199254740992
|
||||
*/
|
||||
|
||||
return ((double)(BitConverter.ToUInt64(b, 0) >> 11) / 9007199254740992);
|
||||
}
|
||||
}
|
||||
|
||||
public enum RDRandError : int {
|
||||
|
|
|
|||
111
Server/Timer.cs
111
Server/Timer.cs
|
|
@ -19,11 +19,13 @@
|
|||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
#if Framework_4_0
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using Server.Diagnostics;
|
||||
|
||||
namespace Server
|
||||
|
|
@ -136,7 +138,7 @@ namespace Server
|
|||
|
||||
public class TimerThread
|
||||
{
|
||||
private static Queue m_ChangeQueue = Queue.Synchronized( new Queue() );
|
||||
private static Dictionary<Timer,TimerChangeEntry> m_Changed = new Dictionary<Timer,TimerChangeEntry>();
|
||||
|
||||
private static long[] m_NextPriorities = new long[8];
|
||||
private static long[] m_PriorityDelays = new long[8]
|
||||
|
|
@ -215,30 +217,29 @@ namespace Server
|
|||
|
||||
public void Free()
|
||||
{
|
||||
//m_InstancePool.Enqueue( this );
|
||||
lock (m_InstancePool) {
|
||||
if (m_InstancePool.Count <= 200) // Arbitrary
|
||||
m_InstancePool.Enqueue( this );
|
||||
}
|
||||
}
|
||||
|
||||
private static Queue<TimerChangeEntry> m_InstancePool = new Queue<TimerChangeEntry>();
|
||||
|
||||
public static TimerChangeEntry GetInstance( Timer t, int newIndex, bool isAdd )
|
||||
{
|
||||
TimerChangeEntry e;
|
||||
TimerChangeEntry e = null;
|
||||
|
||||
if ( m_InstancePool.Count > 0 )
|
||||
{
|
||||
e = m_InstancePool.Dequeue();
|
||||
|
||||
if ( e == null )
|
||||
e = new TimerChangeEntry( t, newIndex, isAdd );
|
||||
else
|
||||
{
|
||||
e.m_Timer = t;
|
||||
e.m_NewIndex = newIndex;
|
||||
e.m_IsAdd = isAdd;
|
||||
lock (m_InstancePool) {
|
||||
if ( m_InstancePool.Count > 0 ) {
|
||||
e = m_InstancePool.Dequeue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (e != null) {
|
||||
e.m_Timer = t;
|
||||
e.m_NewIndex = newIndex;
|
||||
e.m_IsAdd = isAdd;
|
||||
} else {
|
||||
e = new TimerChangeEntry( t, newIndex, isAdd );
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +253,8 @@ namespace Server
|
|||
|
||||
public static void Change( Timer t, int newIndex, bool isAdd )
|
||||
{
|
||||
m_ChangeQueue.Enqueue( TimerChangeEntry.GetInstance( t, newIndex, isAdd ) );
|
||||
lock (m_Changed)
|
||||
m_Changed[t] = TimerChangeEntry.GetInstance(t, newIndex, isAdd);
|
||||
m_Signal.Set();
|
||||
}
|
||||
|
||||
|
|
@ -271,34 +273,57 @@ namespace Server
|
|||
Change( t, -1, false );
|
||||
}
|
||||
|
||||
private static void ProcessChangeQueue()
|
||||
private static void ProcessChanged()
|
||||
{
|
||||
while ( m_ChangeQueue.Count > 0 )
|
||||
{
|
||||
TimerChangeEntry tce = (TimerChangeEntry)m_ChangeQueue.Dequeue();
|
||||
Timer timer = tce.m_Timer;
|
||||
int newIndex = tce.m_NewIndex;
|
||||
lock (m_Changed) {
|
||||
#if Framework_4_0
|
||||
Parallel.ForEach(m_Changed.Values, tce => {
|
||||
Timer timer = tce.m_Timer;
|
||||
int newIndex = tce.m_NewIndex;
|
||||
|
||||
if ( timer.m_List != null )
|
||||
timer.m_List.Remove( timer );
|
||||
if (timer.m_List != null)
|
||||
lock (timer.m_List)
|
||||
timer.m_List.Remove(timer);
|
||||
|
||||
if ( tce.m_IsAdd )
|
||||
{
|
||||
timer.m_Next = Core.TickCount + timer.m_Delay;
|
||||
timer.m_Index = 0;
|
||||
if (tce.m_IsAdd) {
|
||||
timer.m_Next = Core.TickCount + timer.m_Delay;
|
||||
timer.m_Index = 0;
|
||||
}
|
||||
|
||||
if (newIndex >= 0) {
|
||||
timer.m_List = m_Timers[newIndex];
|
||||
lock (timer.m_List)
|
||||
timer.m_List.Add(timer);
|
||||
} else {
|
||||
timer.m_List = null;
|
||||
}
|
||||
|
||||
tce.Free();
|
||||
});
|
||||
#else
|
||||
foreach (TimerChangeEntry tce in m_Changed.Values) {
|
||||
Timer timer = tce.m_Timer;
|
||||
int newIndex = tce.m_NewIndex;
|
||||
|
||||
if (timer.m_List != null)
|
||||
timer.m_List.Remove(timer);
|
||||
|
||||
if (tce.m_IsAdd) {
|
||||
timer.m_Next = Core.TickCount + timer.m_Delay;
|
||||
timer.m_Index = 0;
|
||||
}
|
||||
|
||||
if (newIndex >= 0) {
|
||||
timer.m_List = m_Timers[newIndex];
|
||||
timer.m_List.Add(timer);
|
||||
} else {
|
||||
timer.m_List = null;
|
||||
}
|
||||
|
||||
tce.Free();
|
||||
}
|
||||
|
||||
if ( newIndex >= 0 )
|
||||
{
|
||||
timer.m_List = m_Timers[newIndex];
|
||||
timer.m_List.Add( timer );
|
||||
}
|
||||
else
|
||||
{
|
||||
timer.m_List = null;
|
||||
}
|
||||
|
||||
tce.Free();
|
||||
#endif
|
||||
m_Changed.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -313,7 +338,7 @@ namespace Server
|
|||
|
||||
while ( !Core.Closing )
|
||||
{
|
||||
ProcessChangeQueue();
|
||||
ProcessChanged();
|
||||
|
||||
loaded = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -789,7 +789,7 @@ namespace Server
|
|||
|
||||
public static bool RandomBool()
|
||||
{
|
||||
return (RandomImpl.Next(2) == 0);
|
||||
return RandomImpl.NextBool();
|
||||
}
|
||||
|
||||
public static int RandomMinMax( int min, int max )
|
||||
|
|
@ -810,16 +810,11 @@ namespace Server
|
|||
|
||||
public static int Random( int from, int count )
|
||||
{
|
||||
if ( count == 0 )
|
||||
{
|
||||
if ( count == 0 ) {
|
||||
return from;
|
||||
}
|
||||
else if ( count > 0 )
|
||||
{
|
||||
} else if ( count > 0 ) {
|
||||
return from + RandomImpl.Next(count);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return from - RandomImpl.Next(-count);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue