201 lines
6.8 KiB
C#
201 lines
6.8 KiB
C#
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity - Singularity ABI
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// File: SyncHandle.cs
|
|
//
|
|
// Note:
|
|
//
|
|
|
|
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using Microsoft.Singularity;
|
|
using Microsoft.Singularity.Memory;
|
|
using Microsoft.Singularity.V1.Services;
|
|
|
|
namespace Microsoft.Singularity.V1.Threads
|
|
{
|
|
[CLSCompliant(false)]
|
|
public struct SyncHandle
|
|
{
|
|
public readonly UIntPtr id;
|
|
|
|
public static readonly SyncHandle Zero = new SyncHandle();
|
|
|
|
[Inline]
|
|
public static implicit operator SyncHandle(MutexHandle handle)
|
|
{
|
|
return new SyncHandle(handle.id);
|
|
}
|
|
|
|
[Inline]
|
|
public static implicit operator SyncHandle(AutoResetEventHandle handle)
|
|
{
|
|
return new SyncHandle(handle.id);
|
|
}
|
|
|
|
[Inline]
|
|
public static implicit operator SyncHandle(ManualResetEventHandle handle)
|
|
{
|
|
return new SyncHandle(handle.id);
|
|
}
|
|
|
|
internal SyncHandle(UIntPtr id)
|
|
{
|
|
this.id = id;
|
|
}
|
|
|
|
#if false
|
|
/// REVIEW: generalizes waiting across events and endpoints
|
|
/// should review to ensure this is safe
|
|
public WaitHandle GetWaitHandle() {
|
|
return HandleTable.GetHandle(id) as WaitHandle;
|
|
}
|
|
|
|
public static implicit operator WaitHandle(SyncHandle s) {
|
|
return HandleTable.GetHandle(s.id) as WaitHandle;
|
|
}
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// The following methods could be moved to WaitHandle if we had
|
|
// struct inheritance.
|
|
//
|
|
[ExternalEntryPoint]
|
|
public static bool WaitOne(SyncHandle handle)
|
|
{
|
|
//
|
|
// Convert the handle to a waitHandle; wait on the waitHandle.
|
|
//
|
|
WaitHandle waitHandle = HandleTable.GetHandle(handle.id) as WaitHandle;
|
|
bool ret = waitHandle.WaitOne(SchedulerTime.MaxValue);
|
|
|
|
Tracing.Log(Tracing.Debug, "SyncHandle.WaitOne(id={0:x8})", handle.id);
|
|
|
|
return ret;
|
|
}
|
|
|
|
[ExternalEntryPoint(IgnoreCallerTransition=1)]
|
|
public static bool WaitOneNoGC(SyncHandle handle)
|
|
{
|
|
WaitHandle waitHandle =
|
|
HandleTable.GetHandle(handle.id) as WaitHandle;
|
|
bool ret = waitHandle.WaitOne(SchedulerTime.MaxValue);
|
|
Tracing.Log(Tracing.Debug, "SyncHandle.WaitOneNoGC(id={0:x8})",
|
|
handle.id);
|
|
return ret;
|
|
}
|
|
|
|
[ExternalEntryPoint]
|
|
public static bool WaitOne(SyncHandle handle,
|
|
TimeSpan timeout)
|
|
{
|
|
//
|
|
// Convert the handle to a waitHandle; wait on the waitHandle.
|
|
//
|
|
WaitHandle waitHandle = HandleTable.GetHandle(handle.id) as WaitHandle;
|
|
bool ret = waitHandle.WaitOne(SchedulerTime.Now + timeout);
|
|
|
|
Tracing.Log(Tracing.Debug, "SyncHandle.WaitOne(id={0:x8}, time=)",
|
|
handle.id);
|
|
|
|
return ret;
|
|
}
|
|
|
|
[ExternalEntryPoint]
|
|
public static bool WaitOne(SyncHandle handle,
|
|
SchedulerTime stop)
|
|
{
|
|
//
|
|
// Convert the handle to a waitHandle; wait on the waitHandle.
|
|
//
|
|
WaitHandle waitHandle = HandleTable.GetHandle(handle.id) as WaitHandle;
|
|
bool ret = waitHandle.WaitOne(stop);
|
|
|
|
Tracing.Log(Tracing.Debug, "SyncHandle.WaitOne(id={0:x8}, stop=)",
|
|
handle.id);
|
|
|
|
return ret;
|
|
}
|
|
|
|
[ExternalEntryPoint]
|
|
[CLSCompliant(false)]
|
|
public static unsafe int WaitAny(SyncHandle * handles,
|
|
int handleCount)
|
|
{
|
|
WaitHandle[] waits = Thread.CurrentThread.GetSyncHandles(handleCount);
|
|
for (int i = 0; i < handleCount; i++) {
|
|
waits[i] = HandleTable.GetHandle(handles[i].id) as WaitHandle;;
|
|
}
|
|
|
|
int ret = WaitHandle.WaitAny(waits, handleCount, SchedulerTime.MaxValue);
|
|
|
|
Tracing.Log(Tracing.Debug,
|
|
"SyncHandle.WaitAny(handles={0:x8}, count={1}) = {2}",
|
|
(UIntPtr)handles,
|
|
(UIntPtr)unchecked((uint)handleCount),
|
|
(UIntPtr)unchecked((uint)ret));
|
|
|
|
for (int i = 0; i < handleCount; i++) {
|
|
waits[i] = null;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
[ExternalEntryPoint]
|
|
[CLSCompliant(false)]
|
|
public static unsafe int WaitAny(SyncHandle * handles,
|
|
int handleCount,
|
|
TimeSpan timeout)
|
|
{
|
|
WaitHandle[] waits = Thread.CurrentThread.GetSyncHandles(handleCount);
|
|
for (int i = 0; i < handleCount; i++) {
|
|
waits[i] = HandleTable.GetHandle(handles[i].id) as WaitHandle;;
|
|
}
|
|
|
|
int ret = WaitHandle.WaitAny(waits, handleCount,
|
|
SchedulerTime.Now + timeout);
|
|
|
|
Tracing.Log(Tracing.Debug,
|
|
"SyncHandle.WaitAny(handles={0:x8}, count={1}, time=) = {2}",
|
|
(UIntPtr)handles,
|
|
(UIntPtr)unchecked((uint)handleCount),
|
|
(UIntPtr)unchecked((uint)ret));
|
|
|
|
for (int i = 0; i < handleCount; i++) {
|
|
waits[i] = null;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
[ExternalEntryPoint]
|
|
[CLSCompliant(false)]
|
|
public static unsafe int WaitAny(SyncHandle * handles,
|
|
int handleCount,
|
|
SchedulerTime stop)
|
|
{
|
|
WaitHandle[] waits = Thread.CurrentThread.GetSyncHandles(handleCount);
|
|
for (int i = 0; i < handleCount; i++) {
|
|
waits[i] = HandleTable.GetHandle(handles[i].id) as WaitHandle;;
|
|
}
|
|
|
|
int ret = WaitHandle.WaitAny(waits, handleCount, stop);
|
|
|
|
Tracing.Log(Tracing.Debug,
|
|
"SyncHandle.WaitAny(handles={0:x8}, count={1}, stop=) = {2}",
|
|
(UIntPtr)handles,
|
|
(UIntPtr)unchecked((uint)handleCount),
|
|
(UIntPtr)unchecked((uint)ret));
|
|
|
|
for (int i = 0; i < handleCount; i++) {
|
|
waits[i] = null;
|
|
}
|
|
return ret;
|
|
}
|
|
}
|
|
}
|