cool stuff
but im a little bit confused.. why didnt the old chess find this bug? if it ran with all the combinations of context switches, wouldnt the assert be false?
CHESS only places schedule points at synchronization points (calls to System.Threading API, volatiles, interlocked increments). So you need data race detection to uncover more bugs. CHESS now has an option /preemptaccesses that places schedule points before every read/write. However, as currently implemented, this has high overhead.
-- Tom
I spent a couple of time to build a good, working solution for .NET 2.0 / 3.5, so you do not need to wait and install .NET 4.0
Can you test it using CHESS?
Abstract:
public abstract class PluginBaseWorkItem<T> { private static object _sync = new object(); private T _item; public T Item { get { return _item; } } public void Run() { List<WaitHandle> _waitHandles = new List<WaitHandle>(); for (int i = 0; i < TaskCount; i++) { _waitHandles.Add(new AutoResetEvent(false)); } for (int i = 0; i < TaskCount; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessHandle), _waitHandles[i]); } WaitHandle.WaitAll(_waitHandles.ToArray()); } protected abstract void ProcessItem(); protected void SetValue(T item) { _item = item; } protected T GetValue() { return _item; } protected virtual int TaskCount { get { return Environment.ProcessorCount; } } private void Process() { ProcessItem(); } private void ProcessHandle(object sync) { AutoResetEvent waitHandle = (AutoResetEvent)sync; Process(); waitHandle.Set(); } } private class WorkItem : PluginBaseWorkItem<Puzzle> { protected override void ProcessItem() { DlxEngine engine = new DlxEngine(); Puzzle value = engine.Generate(20); lock (this) { Puzzle item = GetValue(); if (item == null || value.Rating > item.Rating) { SetValue(value); } } } } public static IPuzzle Create() { WorkItem workItem = new WorkItem(); workItem.Run(); IPuzzle puzzle = workItem.Item; return Create(puzzle.Text, puzzle.Seed); }
public abstract class PluginBaseWorkItem<T>
{
private static object _sync = new object();
private T _item;
public T Item { get { return _item; } }
public void Run()
List<WaitHandle> _waitHandles = new List<WaitHandle>();
for (int i = 0; i < TaskCount; i++)
_waitHandles.Add(new AutoResetEvent(false));
}
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessHandle), _waitHandles[i]);
WaitHandle.WaitAll(_waitHandles.ToArray());
protected abstract void ProcessItem();
protected void SetValue(T item)
_item = item;
protected T GetValue()
return _item;
protected virtual int TaskCount { get { return Environment.ProcessorCount; } }
private void Process()
ProcessItem();
private void ProcessHandle(object sync)
AutoResetEvent waitHandle = (AutoResetEvent)sync;
Process();
waitHandle.Set();
private class WorkItem : PluginBaseWorkItem<Puzzle>
{ protected override void ProcessItem() { DlxEngine engine = new DlxEngine(); Puzzle value = engine.Generate(20); lock (this) { Puzzle item = GetValue(); if (item == null || value.Rating > item.Rating) { SetValue(value); } } } } public static IPuzzle Create() { WorkItem workItem = new WorkItem(); workItem.Run(); IPuzzle puzzle = workItem.Item; return Create(puzzle.Text, puzzle.Seed); }
protected override void ProcessItem()
DlxEngine engine = new DlxEngine();
Puzzle value = engine.Generate(20);
lock (this)
Puzzle item = GetValue();
if (item == null || value.Rating > item.Rating)
SetValue(value);
public static IPuzzle Create()
WorkItem workItem = new WorkItem();
workItem.Run();
IPuzzle puzzle = workItem.Item;
return Create(puzzle.Text, puzzle.Seed);
Excellent post! Great use of Picture-in-picture technology. Improves user experience a lot
and
seems to be a bug in the comment recording. my comment box showed up blank while the comment showed up under hack2roothotmai??!!
I tested it, it works !Many thanks for this excellent post !!!--
Thanks hack2roothotmai, it works perfectly...
I was looking for something like that
Thanks hack2roothotmai. It definitely works.
It's ok, it works !! Thanks a lot hack2root...
David
Good job ... thank you for this help.