diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/IClientAPI.cs | 59 | ||||
-rw-r--r-- | OpenSim/Framework/PriorityQueue.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs) | 43 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 17 |
3 files changed, 92 insertions, 27 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index eea9107..f187468 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -576,34 +576,69 @@ namespace OpenSim.Framework | |||
576 | 576 | ||
577 | public class IEntityUpdate | 577 | public class IEntityUpdate |
578 | { | 578 | { |
579 | public ISceneEntity Entity; | 579 | private ISceneEntity m_entity; |
580 | public uint Flags; | 580 | private uint m_flags; |
581 | private int m_updateTime; | ||
582 | |||
583 | public ISceneEntity Entity | ||
584 | { | ||
585 | get { return m_entity; } | ||
586 | } | ||
587 | |||
588 | public uint Flags | ||
589 | { | ||
590 | get { return m_flags; } | ||
591 | } | ||
592 | |||
593 | public int UpdateTime | ||
594 | { | ||
595 | get { return m_updateTime; } | ||
596 | } | ||
581 | 597 | ||
582 | public virtual void Update(IEntityUpdate update) | 598 | public virtual void Update(IEntityUpdate update) |
583 | { | 599 | { |
584 | this.Flags |= update.Flags; | 600 | m_flags |= update.Flags; |
601 | |||
602 | // Use the older of the updates as the updateTime | ||
603 | if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0) | ||
604 | m_updateTime = update.UpdateTime; | ||
585 | } | 605 | } |
586 | 606 | ||
587 | public IEntityUpdate(ISceneEntity entity, uint flags) | 607 | public IEntityUpdate(ISceneEntity entity, uint flags) |
588 | { | 608 | { |
589 | Entity = entity; | 609 | m_entity = entity; |
590 | Flags = flags; | 610 | m_flags = flags; |
611 | m_updateTime = Util.EnvironmentTickCount(); | ||
612 | } | ||
613 | |||
614 | public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime) | ||
615 | { | ||
616 | m_entity = entity; | ||
617 | m_flags = flags; | ||
618 | m_updateTime = updateTime; | ||
591 | } | 619 | } |
592 | } | 620 | } |
593 | |||
594 | 621 | ||
595 | public class EntityUpdate : IEntityUpdate | 622 | public class EntityUpdate : IEntityUpdate |
596 | { | 623 | { |
597 | // public ISceneEntity Entity; | 624 | private float m_timeDilation; |
598 | // public PrimUpdateFlags Flags; | 625 | |
599 | public float TimeDilation; | 626 | public float TimeDilation |
627 | { | ||
628 | get { return m_timeDilation; } | ||
629 | } | ||
600 | 630 | ||
601 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) | 631 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) |
602 | : base(entity,(uint)flags) | 632 | : base(entity, (uint)flags) |
603 | { | 633 | { |
604 | //Entity = entity; | ||
605 | // Flags = flags; | 634 | // Flags = flags; |
606 | TimeDilation = timedilation; | 635 | m_timeDilation = timedilation; |
636 | } | ||
637 | |||
638 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation, Int32 updateTime) | ||
639 | : base(entity,(uint)flags,updateTime) | ||
640 | { | ||
641 | m_timeDilation = timedilation; | ||
607 | } | 642 | } |
608 | } | 643 | } |
609 | 644 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs index b62ec07..eec2a92 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs +++ b/OpenSim/Framework/PriorityQueue.cs | |||
@@ -34,20 +34,21 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Framework.Client; | 34 | using OpenSim.Framework.Client; |
35 | using log4net; | 35 | using log4net; |
36 | 36 | ||
37 | namespace OpenSim.Region.ClientStack.LindenUDP | 37 | namespace OpenSim.Framework |
38 | { | 38 | { |
39 | public class PriorityQueue | 39 | public class PriorityQueue |
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 42 | ||
43 | internal delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); | 43 | public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); |
44 | 44 | ||
45 | // Heap[0] for self updates | 45 | // Heap[0] for self updates |
46 | // Heap[1..12] for entity updates | 46 | // Heap[1..12] for entity updates |
47 | 47 | ||
48 | internal const uint m_numberOfQueues = 12; | 48 | public const uint NumberOfQueues = 12; |
49 | public const uint ImmediateQueue = 0; | ||
49 | 50 | ||
50 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[m_numberOfQueues]; | 51 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues]; |
51 | private Dictionary<uint, LookupItem> m_lookupTable; | 52 | private Dictionary<uint, LookupItem> m_lookupTable; |
52 | private uint m_nextQueue = 0; | 53 | private uint m_nextQueue = 0; |
53 | private UInt64 m_nextRequest = 0; | 54 | private UInt64 m_nextRequest = 0; |
@@ -57,9 +58,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
57 | get { return this.m_syncRoot; } | 58 | get { return this.m_syncRoot; } |
58 | } | 59 | } |
59 | 60 | ||
60 | internal PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } | 61 | public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } |
61 | 62 | ||
62 | internal PriorityQueue(int capacity) | 63 | public PriorityQueue(int capacity) |
63 | { | 64 | { |
64 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); | 65 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); |
65 | 66 | ||
@@ -67,7 +68,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
67 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | 68 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); |
68 | } | 69 | } |
69 | 70 | ||
70 | internal int Count | 71 | public int Count |
71 | { | 72 | { |
72 | get | 73 | get |
73 | { | 74 | { |
@@ -91,7 +92,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
91 | lookup.Heap.Remove(lookup.Handle); | 92 | lookup.Heap.Remove(lookup.Handle); |
92 | } | 93 | } |
93 | 94 | ||
94 | pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1); | 95 | pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1); |
95 | lookup.Heap = m_heaps[pqueue]; | 96 | lookup.Heap = m_heaps[pqueue]; |
96 | lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle); | 97 | lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle); |
97 | m_lookupTable[localid] = lookup; | 98 | m_lookupTable[localid] = lookup; |
@@ -99,18 +100,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
99 | return true; | 100 | return true; |
100 | } | 101 | } |
101 | 102 | ||
102 | internal bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) | 103 | public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) |
103 | { | 104 | { |
104 | for (int i = 0; i < m_numberOfQueues; ++i) | 105 | // If there is anything in priority queue 0, return it first no |
106 | // matter what else. Breaks fairness. But very useful. | ||
107 | if (m_heaps[ImmediateQueue].Count > 0) | ||
108 | { | ||
109 | MinHeapItem item = m_heaps[ImmediateQueue].RemoveMin(); | ||
110 | m_lookupTable.Remove(item.Value.Entity.LocalId); | ||
111 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | ||
112 | value = item.Value; | ||
113 | |||
114 | return true; | ||
115 | } | ||
116 | |||
117 | for (int i = 0; i < NumberOfQueues; ++i) | ||
105 | { | 118 | { |
106 | // To get the fair queing, we cycle through each of the | 119 | // To get the fair queing, we cycle through each of the |
107 | // queues when finding an element to dequeue, this code | 120 | // queues when finding an element to dequeue, this code |
108 | // assumes that the distribution of updates in the queues | 121 | // assumes that the distribution of updates in the queues |
109 | // is polynomial, probably quadractic (eg distance of PI * R^2) | 122 | // is polynomial, probably quadractic (eg distance of PI * R^2) |
110 | uint h = (uint)((m_nextQueue + i) % m_numberOfQueues); | 123 | uint h = (uint)((m_nextQueue + i) % NumberOfQueues); |
111 | if (m_heaps[h].Count > 0) | 124 | if (m_heaps[h].Count > 0) |
112 | { | 125 | { |
113 | m_nextQueue = (uint)((h + 1) % m_numberOfQueues); | 126 | m_nextQueue = (uint)((h + 1) % NumberOfQueues); |
114 | 127 | ||
115 | MinHeapItem item = m_heaps[h].RemoveMin(); | 128 | MinHeapItem item = m_heaps[h].RemoveMin(); |
116 | m_lookupTable.Remove(item.Value.Entity.LocalId); | 129 | m_lookupTable.Remove(item.Value.Entity.LocalId); |
@@ -126,7 +139,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
126 | return false; | 139 | return false; |
127 | } | 140 | } |
128 | 141 | ||
129 | internal void Reprioritize(UpdatePriorityHandler handler) | 142 | public void Reprioritize(UpdatePriorityHandler handler) |
130 | { | 143 | { |
131 | MinHeapItem item; | 144 | MinHeapItem item; |
132 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) | 145 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) |
@@ -140,7 +153,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
140 | { | 153 | { |
141 | // unless the priority queue has changed, there is no need to modify | 154 | // unless the priority queue has changed, there is no need to modify |
142 | // the entry | 155 | // the entry |
143 | pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1); | 156 | pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1); |
144 | if (pqueue != item.PriorityQueue) | 157 | if (pqueue != item.PriorityQueue) |
145 | { | 158 | { |
146 | lookup.Heap.Remove(lookup.Handle); | 159 | lookup.Heap.Remove(lookup.Handle); |
@@ -164,7 +177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
164 | public override string ToString() | 177 | public override string ToString() |
165 | { | 178 | { |
166 | string s = ""; | 179 | string s = ""; |
167 | for (int i = 0; i < m_numberOfQueues; i++) | 180 | for (int i = 0; i < NumberOfQueues; i++) |
168 | { | 181 | { |
169 | if (s != "") s += ","; | 182 | if (s != "") s += ","; |
170 | s += m_heaps[i].Count.ToString(); | 183 | s += m_heaps[i].Count.ToString(); |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 3f676f9..366a38f 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -1549,6 +1549,23 @@ namespace OpenSim.Framework | |||
1549 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); | 1549 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); |
1550 | } | 1550 | } |
1551 | 1551 | ||
1552 | // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount | ||
1553 | // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). | ||
1554 | // A positive return value indicates A occured later than B | ||
1555 | public static Int32 EnvironmentTickCountCompare(Int32 tcA, Int32 tcB) | ||
1556 | { | ||
1557 | // A, B and TC are all between 0 and 0x3fffffff | ||
1558 | int tc = EnvironmentTickCount(); | ||
1559 | |||
1560 | if (tc - tcA >= 0) | ||
1561 | tcA += EnvironmentTickCountMask + 1; | ||
1562 | |||
1563 | if (tc - tcB >= 0) | ||
1564 | tcB += EnvironmentTickCountMask + 1; | ||
1565 | |||
1566 | return tcA - tcB; | ||
1567 | } | ||
1568 | |||
1552 | /// <summary> | 1569 | /// <summary> |
1553 | /// Prints the call stack at any given point. Useful for debugging. | 1570 | /// Prints the call stack at any given point. Useful for debugging. |
1554 | /// </summary> | 1571 | /// </summary> |