ubode replace a locklessqueue by .net concurrentqueue

0.9.1.0-post-fixes
UbitUmarov 2019-01-29 13:49:29 +00:00
parent f1076607dc
commit 6bc8e2413f
2 changed files with 84 additions and 120 deletions

View File

@ -1143,7 +1143,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
/// This is the avatar's movement control + PID Controller /// This is the avatar's movement control + PID Controller
/// </summary> /// </summary>
/// <param name="timeStep"></param> /// <param name="timeStep"></param>
public void Move(List<OdeCharacter> defects) public void Move()
{ {
if(Body == IntPtr.Zero) if(Body == IntPtr.Zero)
return; return;
@ -1180,40 +1180,50 @@ namespace OpenSim.Region.PhysicsModule.ubOde
_zeroPosition = localpos; _zeroPosition = localpos;
} }
if(!localpos.IsFinite())
{
m_log.Warn("[PHYSICS]: Avatar Position is non-finite!");
defects.Add(this);
// _parent_scene.RemoveCharacter(this);
// destroy avatar capsule and related ODE data
AvatarGeomAndBodyDestroy();
return;
}
// check outbounds forcing to be in world // check outbounds forcing to be in world
bool fixbody = false; bool fixbody = false;
if(localpos.X < 0.0f) float tmp = localpos.X;
if ((Single.IsNaN(tmp) || Single.IsInfinity(tmp)))
{
fixbody = true;
localpos.X = 128f;
}
else if (tmp < 0.0f)
{ {
fixbody = true; fixbody = true;
localpos.X = 0.1f; localpos.X = 0.1f;
} }
else if(localpos.X > m_parent_scene.WorldExtents.X - 0.1f) else if (tmp > m_parent_scene.WorldExtents.X - 0.1f)
{ {
fixbody = true; fixbody = true;
localpos.X = m_parent_scene.WorldExtents.X - 0.1f; localpos.X = m_parent_scene.WorldExtents.X - 0.1f;
} }
if(localpos.Y < 0.0f)
tmp = localpos.Y;
if ((Single.IsNaN(tmp) || Single.IsInfinity(tmp)))
{
fixbody = true;
localpos.X = 128f;
}
else if (tmp < 0.0f)
{ {
fixbody = true; fixbody = true;
localpos.Y = 0.1f; localpos.Y = 0.1f;
} }
else if(localpos.Y > m_parent_scene.WorldExtents.Y - 0.1) else if(tmp > m_parent_scene.WorldExtents.Y - 0.1)
{ {
fixbody = true; fixbody = true;
localpos.Y = m_parent_scene.WorldExtents.Y - 0.1f; localpos.Y = m_parent_scene.WorldExtents.Y - 0.1f;
} }
if(fixbody)
tmp = localpos.Z;
if ((Single.IsNaN(tmp) || Single.IsInfinity(tmp)))
{
fixbody = true;
localpos.Z = 128f;
}
if (fixbody)
{ {
m_freemove = false; m_freemove = false;
SafeNativeMethods.BodySetPosition(Body,localpos.X,localpos.Y,localpos.Z); SafeNativeMethods.BodySetPosition(Body,localpos.X,localpos.Y,localpos.Z);
@ -1387,7 +1397,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
_zeroFlag = false; _zeroFlag = false;
fz /= m_PIDHoverTau; fz /= m_PIDHoverTau;
float tmp = Math.Abs(fz); tmp = Math.Abs(fz);
if(tmp > 50) if(tmp > 50)
fz = 50 * Math.Sign(fz); fz = 50 * Math.Sign(fz);
else if(tmp < 0.1) else if(tmp < 0.1)
@ -1573,19 +1583,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
if(vec.IsFinite()) if(vec.IsFinite())
{ {
if(vec.X != 0 || vec.Y !=0 || vec.Z !=0) if((vec.X != 0 || vec.Y !=0 || vec.Z !=0))
SafeNativeMethods.BodyAddForce(Body,vec.X,vec.Y,vec.Z); SafeNativeMethods.BodyAddForce(Body,vec.X,vec.Y,vec.Z);
} }
else
{
m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()");
m_log.Warn("[PHYSICS]: Avatar Position is non-finite!");
defects.Add(this);
// _parent_scene.RemoveCharacter(this);
// destroy avatar capsule and related ODE data
AvatarGeomAndBodyDestroy();
return;
}
// update our local ideia of position velocity and aceleration // update our local ideia of position velocity and aceleration
// _position = localpos; // _position = localpos;

View File

@ -26,9 +26,10 @@
*/ */
// Revision 2011/12/13 by Ubit Umarov // Revision 2011/12/13 by Ubit Umarov
//#define SPAM
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -158,7 +159,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public struct ODEchangeitem public struct ODEchangeitem
{ {
public PhysicsActor actor; public PhysicsActor actor;
public OdeCharacter character;
public changes what; public changes what;
public Object arg; public Object arg;
} }
@ -230,7 +230,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); private HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
private HashSet<OdePrim> _activegroups = new HashSet<OdePrim>(); private HashSet<OdePrim> _activegroups = new HashSet<OdePrim>();
public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>(); public ConcurrentQueue<ODEchangeitem> ChangesQueue = new ConcurrentQueue<ODEchangeitem>();
/// <summary> /// <summary>
/// A list of actors that should receive collision events. /// A list of actors that should receive collision events.
@ -621,8 +621,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
return; return;
} }
// Figure out how many contact points we have // Figure out how many contact points we have
int count = 0; int count = 0;
try try
@ -1180,12 +1178,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
//m_log.Debug("[PHYSICS]:ODELOCK"); //m_log.Debug("[PHYSICS]:ODELOCK");
if (world == IntPtr.Zero) if (world == IntPtr.Zero)
return; return;
lock (SimulationLock) ((OdeCharacter) actor).Destroy();
lock (OdeLock)
{
SafeNativeMethods.AllocateODEDataForThread(0);
((OdeCharacter) actor).Destroy();
}
} }
public void addActivePrim(OdePrim activatePrim) public void addActivePrim(OdePrim activatePrim)
@ -1224,7 +1217,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid); return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid);
} }
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
Vector3 size, Quaternion rotation, bool isPhysical, uint localid) Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
{ {
@ -1244,6 +1236,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
_activeprims.Remove(deactivatePrim); _activeprims.Remove(deactivatePrim);
} }
} }
public void remActiveGroup(OdePrim deactivatePrim) public void remActiveGroup(OdePrim deactivatePrim)
{ {
lock (_activegroups) lock (_activegroups)
@ -1258,25 +1251,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// removed in the next physics simulate pass. // removed in the next physics simulate pass.
if (prim is OdePrim) if (prim is OdePrim)
{ {
// lock (OdeLock) OdePrim p = (OdePrim)prim;
{ p.setPrimForRemoval();
OdePrim p = (OdePrim)prim;
p.setPrimForRemoval();
}
} }
} }
public void RemovePrimThreadLocked(OdePrim prim) public void RemovePrimThreadLocked(OdePrim prim)
{ {
//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName);
lock (prim) lock (_prims)
{ _prims.Remove(prim.LocalID);
// RemoveCollisionEventReporting(prim);
lock (_prims)
_prims.Remove(prim.LocalID);
}
} }
public void addToPrims(OdePrim prim) public void addToPrims(OdePrim prim)
@ -1405,12 +1389,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde
/// to use in place of old taint mechanism so changes do have a time sequence /// to use in place of old taint mechanism so changes do have a time sequence
/// </summary> /// </summary>
public void AddChange(PhysicsActor actor, changes what, Object arg) public void AddChange(PhysicsActor _actor, changes _what, Object _arg)
{ {
ODEchangeitem item = new ODEchangeitem(); if (world == IntPtr.Zero)
item.actor = actor; return;
item.what = what;
item.arg = arg; ODEchangeitem item = new ODEchangeitem
{
actor = _actor,
what = _what,
arg = _arg
};
ChangesQueue.Enqueue(item); ChangesQueue.Enqueue(item);
} }
@ -1430,22 +1419,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde
lock (OdeLock) lock (OdeLock)
{ {
if (world == IntPtr.Zero) if (world == IntPtr.Zero)
{
ChangesQueue.Clear();
return; return;
}
SafeNativeMethods.AllocateODEDataForThread(~0U);
ODEchangeitem item; ODEchangeitem item;
int donechanges = 0; int donechanges = 0;
if (ChangesQueue.Count > 0) if (!ChangesQueue.IsEmpty)
{ {
m_log.InfoFormat("[ubOde] start processing pending actor operations"); m_log.InfoFormat("[ubOde] start processing pending actor operations");
int tstart = Util.EnvironmentTickCount(); int tstart = Util.EnvironmentTickCount();
while (ChangesQueue.Dequeue(out item)) SafeNativeMethods.AllocateODEDataForThread(~0U);
while (ChangesQueue.TryDequeue(out item))
{ {
if (item.actor != null) if (item.actor != null)
{ {
@ -1511,13 +1497,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
lock (OdeLock) lock (OdeLock)
{ {
if (world == IntPtr.Zero)
{
ChangesQueue.Clear();
return 0;
}
ODEchangeitem item;
// d.WorldSetQuickStepNumIterations(world, curphysiteractions); // d.WorldSetQuickStepNumIterations(world, curphysiteractions);
@ -1539,17 +1518,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde
*/ */
SafeNativeMethods.AllocateODEDataForThread(~0U); SafeNativeMethods.AllocateODEDataForThread(~0U);
if (ChangesQueue.Count > 0) if (!ChangesQueue.IsEmpty)
{ {
while (ChangesQueue.Dequeue(out item)) ODEchangeitem item;
while (ChangesQueue.TryDequeue(out item))
{ {
if (item.actor != null) if (item.actor != null)
{ {
try try
{ {
lock (SimulationLock) lock (SimulationLock)
{ {
if (item.actor is OdeCharacter) if (item.actor is OdeCharacter)
((OdeCharacter)item.actor).DoAChange(item.what, item.arg); ((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
else if (((OdePrim)item.actor).DoAChange(item.what, item.arg)) else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
RemovePrimThreadLocked((OdePrim)item.actor); RemovePrimThreadLocked((OdePrim)item.actor);
@ -1575,31 +1556,20 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// clear pointer/counter to contacts to pass into joints // clear pointer/counter to contacts to pass into joints
m_global_contactcount = 0; m_global_contactcount = 0;
// tmpTime = Util.GetTimeStampMS();
// tmpTime = Util.GetTimeStampMS();
// Move characters
lock (_characters)
{
List<OdeCharacter> defects = new List<OdeCharacter>();
foreach (OdeCharacter actor in _characters)
{
if (actor != null)
actor.Move(defects);
}
if (defects.Count != 0)
{
foreach (OdeCharacter defect in defects)
{
RemoveCharacter(defect);
}
defects.Clear();
}
}
// Move other active objects
lock (SimulationLock) lock (SimulationLock)
{ {
// Move characters
lock (_characters)
{
foreach (OdeCharacter actor in _characters)
{
actor.Move();
}
}
// Move other active objects
lock (_activegroups) lock (_activegroups)
{ {
foreach (OdePrim aprim in _activegroups) foreach (OdePrim aprim in _activegroups)
@ -1629,9 +1599,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
List<OdePrim> sleepers = new List<OdePrim>(); List<OdePrim> sleepers = new List<OdePrim>();
foreach (PhysicsActor obj in _collisionEventPrim) foreach (PhysicsActor obj in _collisionEventPrim)
{ {
if (obj == null)
continue;
switch ((ActorTypes)obj.PhysicsActorType) switch ((ActorTypes)obj.PhysicsActorType)
{ {
case ActorTypes.Agent: case ActorTypes.Agent:
@ -1644,10 +1611,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde
if (!pobj.m_outbounds) if (!pobj.m_outbounds)
{ {
pobj.SendCollisions((int)(odetimestepMS)); pobj.SendCollisions((int)(odetimestepMS));
if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected && lock(SimulationLock)
!pobj.m_disabled && !pobj.m_building && {
!SafeNativeMethods.BodyIsEnabled(pobj.Body)) if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected &&
sleepers.Add(pobj); !pobj.m_disabled && !pobj.m_building &&
!SafeNativeMethods.BodyIsEnabled(pobj.Body))
sleepers.Add(pobj);
}
} }
break; break;
} }
@ -1656,17 +1626,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde
foreach(OdePrim prm in sleepers) foreach(OdePrim prm in sleepers)
prm.SleeperAddCollisionEvents(); prm.SleeperAddCollisionEvents();
sleepers.Clear(); sleepers.Clear();
// collisonRepo += Util.GetTimeStampMS() - tmpTime; // collisonRepo += Util.GetTimeStampMS() - tmpTime;
// do a ode simulation step // do a ode simulation step
// tmpTime = Util.GetTimeStampMS(); // tmpTime = Util.GetTimeStampMS();
lock (SimulationLock) lock (SimulationLock)
{ {
SafeNativeMethods.WorldQuickStep(world, ODE_STEPSIZE); SafeNativeMethods.WorldQuickStep(world, ODE_STEPSIZE);
SafeNativeMethods.JointGroupEmpty(contactgroup); SafeNativeMethods.JointGroupEmpty(contactgroup);
} }
// qstepTIme += Util.GetTimeStampMS() - tmpTime; // qstepTIme += Util.GetTimeStampMS() - tmpTime;
// update managed ideia of physical data and do updates to core // update managed ideia of physical data and do updates to core
/* /*
@ -1709,7 +1679,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
// ode.dunlock(world); // ode.dunlock(world);
} }
step_time -= ODE_STEPSIZE; step_time -= ODE_STEPSIZE;
nodeframes++; nodeframes++;
@ -1727,7 +1696,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{ {
RemoveCharacter(chr); RemoveCharacter(chr);
} }
_badCharacter.Clear(); _badCharacter.Clear();
} }
} }
@ -1815,8 +1783,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
mesher.ExpireReleaseMeshs(); mesher.ExpireReleaseMeshs();
m_lastMeshExpire = now; m_lastMeshExpire = now;
} }
} }
return fps; return fps;
@ -2005,6 +1971,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private void InitTerrain() private void InitTerrain()
{ {
lock(SimulationLock)
lock (OdeLock) lock (OdeLock)
{ {
SafeNativeMethods.AllocateODEDataForThread(~0U); SafeNativeMethods.AllocateODEDataForThread(~0U);
@ -2110,6 +2077,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
yt += heightmapWidthSamples; yt += heightmapWidthSamples;
} }
lock(SimulationLock)
lock (OdeLock) lock (OdeLock)
{ {
SafeNativeMethods.GeomOSTerrainDataSetBounds(HeightmapData, minH, maxH); SafeNativeMethods.GeomOSTerrainDataSetBounds(HeightmapData, minH, maxH);
@ -2133,9 +2101,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
public override void Dispose() public override void Dispose()
{ {
lock(SimulationLock)
lock (OdeLock) lock (OdeLock)
{ {
if (world == IntPtr.Zero) if (world == IntPtr.Zero)
return; return;
@ -2152,7 +2120,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
lock (_prims) lock (_prims)
{ {
ChangesQueue.Clear();
foreach (OdePrim prm in _prims.Values) foreach (OdePrim prm in _prims.Values)
{ {
prm.DoAChange(changes.Remove, null); prm.DoAChange(changes.Remove, null);
@ -2168,7 +2135,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
_characters.CopyTo(chtorem); _characters.CopyTo(chtorem);
} }
ChangesQueue.Clear();
foreach (OdeCharacter ch in chtorem) foreach (OdeCharacter ch in chtorem)
ch.DoAChange(changes.Remove, null); ch.DoAChange(changes.Remove, null);
@ -2257,7 +2223,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
} }
} }
public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
{ {
List<ContactResult> ourresults = new List<ContactResult>(); List<ContactResult> ourresults = new List<ContactResult>();
@ -2498,6 +2463,5 @@ namespace OpenSim.Region.PhysicsModule.ubOde
}); });
return 1; return 1;
} }
} }
} }