private void SetKey(TKey key, ref T val) { using (var p = new Pinner(val)) { Unsafe.Write((p.Addr + keyOffset).ToPointer(), key); } }
// Constructors internal Session(Domain domain, SessionConfiguration configuration, bool activate) : base(domain) { Guid = Guid.NewGuid(); IsDebugEventLoggingEnabled = OrmLog.IsLogged(LogLevel.Debug); // Just to cache this value // Both Domain and Configuration are valid references here; // Configuration is already locked Configuration = configuration; Name = configuration.Name; identifier = Interlocked.Increment(ref lastUsedIdentifier); CommandTimeout = configuration.DefaultCommandTimeout; allowSwitching = configuration.Supports(SessionOptions.AllowSwitching); // Handlers Handlers = domain.Handlers; Handler = CreateSessionHandler(); // Caches, registry EntityStateCache = CreateSessionCache(configuration); EntityChangeRegistry = new EntityChangeRegistry(this); EntitySetChangeRegistry = new EntitySetChangeRegistry(this); ReferenceFieldsChangesRegistry = new ReferenceFieldsChangesRegistry(this); entitySetsWithInvalidState = new HashSet <EntitySetBase>(); // Events EntityEvents = new EntityEventBroker(); Events = new SessionEventAccessor(this, false); SystemEvents = new SessionEventAccessor(this, true); // Etc. PairSyncManager = new SyncManager(this); RemovalProcessor = new RemovalProcessor(this); pinner = new Pinner(this); Operations = new OperationRegistry(this); NonPairedReferencesRegistry = new NonPairedReferenceChangesRegistry(this); CommandProcessorContextProvider = new CommandProcessorContextProvider(this); // Validation context ValidationContext = Configuration.Supports(SessionOptions.ValidateEntities) ? (ValidationContext) new RealValidationContext() : new VoidValidationContext(); // Creating Services Services = CreateServices(); disposableSet = new DisposableSet(); remapper = new KeyRemapper(this); disableAutoSaveChanges = !configuration.Supports(SessionOptions.AutoSaveChanges); // Perform activation if (activate) { ActivateInternally(); } // Query endpoint SystemQuery = Query = new QueryEndpoint(new QueryProvider(this)); }
private void SetKeyArray(Array key, ref T val) { using (var p = new Pinner(val)) { Unsafe.CopyBlock((p.Addr + keyOffset).ToPointer(), Unsafe.AsPointer(ref key), (uint)(key.Length * Marshal.SizeOf(key.GetType().GetElementType()))); } }
public void initial_count() { var p = new Pinner(); Assert.Equal(0, p.PinCount); Assert.False(p.IsUnpinnable); }
/// <summary> Construct from a read-only file. </summary> /// <remarks> /// Used when recovering files written by a previous program /// instance from their locations. /// </remarks> public BlockFile(IFileMemory file, uint fileId) { _pinner = new Pinner(); _file = file ?? throw new ArgumentNullException(nameof(file)); FileId = fileId; _flags = new AppendList <ReadFlag>(); var offset = 0L; while (offset < _file.Length) { var block = AtOffset(offset); ref var header = ref block.Header; if (header.Rank != _flags.Count || header.ContentLength < 0 || header.ContentLength + BlockHeader.Size > _file.Length) { // The header of the block appears broken. Do not include // it in the list, and stop scanning (since we don't know // how far to jump ahead). break; } var thisOffset = offset; _flags.Append(ReadFlag.Triggered(() => VerifyAtOffset(thisOffset))); offset += block.RelativeOffsetToNextBlock; }
internal static Object Pin(Object o, Pinner pinner) { if (fAbortVerboseDebug) { VTable.DebugPrint("Aborter: requested pinning on "); VTable.DebugPrint((ulong)Magic.addressOf(o)); VTable.DebugPrint(" in thread "); VTable.DebugPrint((ulong)Magic.addressOf(Thread.CurrentThread)); VTable.DebugPrint(" with pinner = "); VTable.DebugPrint((int)pinner); VTable.DebugPrint("\n"); } UIntPtr oldCoCoWord = CAS(ref MixinObject(o).preHeader.CoCoWord, WithNoForwardNotCopying(o), WithNoForwardCopying(o)); if (!IsForwarded(oldCoCoWord, o)) { // the object is not forwarded - nothing further to do. // (we know that it must now be aborted, since if it // was, then that couldn't have changed; and if it wasn't, // then our CAS would have succeeded.) if (fAbortVerboseDebug && IsCopying(oldCoCoWord)) { VTable.DebugPrint("Aborter: aborted copying on "); VTable.DebugPrint((ulong)Magic.addressOf(o)); VTable.DebugPrint(" in thread "); VTable.DebugPrint((ulong)Magic.addressOf(Thread.CurrentThread)); VTable.DebugPrint("\n"); } if (fBreakOnAbort && Thread.CurrentThread != mainThread && pinner == Pinner.Barrier) { VTable.DebugBreak(); } return(o); } else { VTable.Assert(pinner == Pinner.Barrier, "Encountered a forwarded object in a pin " + "request that did not originate from the " + "barrier"); if (fAbortVerboseDebug) { VTable.DebugPrint("Aborter: encountered forwarded object " + "at "); VTable.DebugPrint((ulong)Magic.addressOf(o)); VTable.DebugPrint(" in thread "); VTable.DebugPrint((ulong)Magic.addressOf(Thread.CurrentThread)); VTable.DebugPrint("\n"); } return(Magic.fromAddress(ForwardPtr(oldCoCoWord))); } }
internal override UIntPtr DoPin(UIntPtr address, Pinner pinner) { UIntPtr baseAddr = FindObjectForInteriorPtr(address); Object o = Magic.fromAddress(baseAddr); UIntPtr offset = address - baseAddr; o = Pin(o, pinner); return(Magic.addressOf(o) + offset); }
private void SetKeyString(string key, ref T val) { using (var p = new Pinner(val)) { fixed(char *s = key) { Unsafe.CopyBlock((p.Addr + keyOffset).ToPointer(), s, (uint)key.Length); } } }
public void pin_too_many() { var p = new Pinner(); for (var i = 0; i < 1023; ++i) { Assert.True(p.TryPin()); } Assert.False(p.TryPin()); Assert.Equal(1023, p.PinCount); }
public async Task pin_concurrent() { var p = new Pinner(); await Task.WhenAll( Enumerable.Range(0, 1023).Select(_ => Task.Run(async() => { p.TryPin(); await Task.Delay(5); p.Unpin(); }))); Assert.Equal(0, p.PinCount); }
public void cannot_pin_unpinnable() { var p = new Pinner(); Assert.True(p.TryPin()); Assert.False(p.MakeUnpinnable()); Assert.Equal(1, p.PinCount); Assert.False(p.TryPin()); Assert.True(p.Unpin()); Assert.Equal(0, p.PinCount); }
public void TestSsse3() { var output = new byte[input.Length * 2]; var written = 0; Pinner.Pin(input, output, (i, o) => { i += input.Length; o += output.Length; written = Utf8HexFormatter.Ssse3.Format(ref i, ref o, input.Length, toLower: true); }); Assert.Equal(expected, output); Assert.Equal(input.Length, written); }
public void TestAvx2() { var output = new char[input.Length * 2]; var written = 0; Pinner.Pin(input, output, (i, o) => { i += input.Length; o += output.Length; written = Utf16HexFormatter.Avx2.Format(ref i, ref o, input.Length); }); Assert.Equal(expected, output); Assert.Equal(input.Length, written); }
public void TestValidSpan() { var actual = new byte[_binary.Length]; Pinner.Pin(_hexMixed, actual, (input, output) => { var inPtr = input; var outPtr = output; var res = Utf16HexParser.Span.TryParse(ref inPtr, _hexMixed.Length, ref outPtr, _binary.Length); Assert.True(res); Assert.Equal(_hexMixed.Length, (int)(inPtr - input)); Assert.Equal(_binary.Length, (int)(outPtr - output)); }); Assert.Equal(_binary, actual); }
internal override UIntPtr DoPin(UIntPtr address, Pinner pinner) { if (fCount) { numPins++; } UIntPtr baseAddr = FindObjectForInteriorPtr(address); if (baseAddr != UIntPtr.Zero) { address = PinDirect(baseAddr, address, pinner); } return(address); }
public void pin_many() { var p = new Pinner(); for (var i = 0; i < 1023; ++i) { Assert.Equal(i, p.PinCount); Assert.True(p.TryPin()); } for (var i = 1023; i > 0; --i) { Assert.Equal(i, p.PinCount); Assert.False(p.Unpin()); } Assert.Equal(0, p.PinCount); }
public void Write(T[] vals) { index.Clear(); accessor.Dispose(); using (var f = File.OpenWrite(path)) { f.SetLength(offset + vals.Length * valueSize); } accessor = new MemoryAccessor(path, 0, pageSize); using (var p = new Pinner(vals)) { for (int i = 0; i < vals.Length; i++) { var ptr = (p.Addr + i * valueSize); /// FIXME: possible fuckup if TKey is not POD type (e.g. string or array) Add(Unsafe.AsRef <TKey>((ptr + keyOffset).ToPointer()), ref Unsafe.AsRef <T>(ptr.ToPointer())); } } }
public async Task multi_threaded_unpinnable() { var p = new Pinner(); p.TryPin(); var loop = Task.Run(() => { while (p.TryPin()) { Assert.False(p.Unpin()); } }); await Task.Delay(10); Assert.False(p.MakeUnpinnable()); await loop; Assert.True(p.Unpin()); }
public void TestInvalidFixed() { var invalid = new char[_hexMixed.Length]; var actual = new byte[_binary.Length]; for (var i = 0; i < _invalids.Length; i++) { _hexMixed.CopyTo(invalid, 0); var expectedPos = _random.Next(0, _hexMixed.Length); invalid[expectedPos] = _invalids[i]; Pinner.Pin(invalid, actual, (input, output) => { var inPtr = input; var outPtr = output; var res = Utf16HexParser.Fixed.TryParse(ref inPtr, _hexMixed.Length, ref outPtr, _binary.Length); Assert.False(res, $"Dig: {_invalids[i].ToString()}"); Assert.Equal(expectedPos, (int)(inPtr - input)); Assert.Equal(expectedPos / 2, (int)(outPtr - output)); }); } }
public void TestInvalidSsse3() { var invalid = new byte[_hexMixed.Length]; var actual = new byte[_binary.Length]; for (var i = 0; i < _invalids.Length; i++) { _hexMixed.CopyTo(invalid.AsSpan()); var expectedPos = _random.Next(0, _hexMixed.Length); invalid[expectedPos] = _invalids[i]; Pinner.Pin(invalid, actual, (input, output) => { var inPtr = input; var outPtr = output; var res = Utf8HexParser.Ssse3.TryParse(ref inPtr, ref outPtr, _binary.Length); Assert.False(res, $"Dig: {_invalids[i]:X}"); Assert.Equal(FastMath.RoundDownTo16(expectedPos), (int)(inPtr - input)); Assert.Equal(FastMath.RoundDownTo16(expectedPos / 2), (int)(outPtr - output)); }); } }
internal abstract UIntPtr DoPin(UIntPtr address, Pinner pinner);
public void making_no_pins_unpinnable_is_true() { var p = new Pinner(); Assert.True(p.MakeUnpinnable()); }
internal static UIntPtr PinDirect(UIntPtr baseAddr, UIntPtr address, Pinner pinner) { Object o = Magic.fromAddress(baseAddr); UIntPtr CoCoWord; bool waited = false; for (;;) { CoCoWord = MixinObject(o).preHeader.CoCoWord; if (IsSimple(CoCoWord) || IsForwarded(CoCoWord)) { break; } else if (IsCopying(CoCoWord)) { VTable.Assert(pinner == Pinner.Barrier); if (fCount) { if (!waited) { waited = true; numWaitPins++; } numPinWaits++; } // wait until it's copied lock (interlock) { CoCoThread t = MixinThread(Thread.CurrentThread); t.pinnedOut = true; Monitor.PulseAll(interlock); while (t.pinnedOut) { Monitor.Wait(interlock); } } // ok, now try again (by the time we get here the // object could already be in the process of being // copied agagin!) } else if (IsTagged(CoCoWord)) { CASCoCoWord(o, Simple(), CoCoWord); NotifyPin(baseAddr); } } // what does it mean to get here? the object cannot // be moved until the next pinning safepoint prior to // a transition out of Idle. VTable.Assert(IsSimple(CoCoWord) || IsForwarded(CoCoWord)); // correct address if (IsForwarded(CoCoWord)) { address -= baseAddr; address += ForwardPtr(CoCoWord); } return(address); }