示例#1
0
 private void SetKey(TKey key, ref T val)
 {
     using (var p = new Pinner(val))
     {
         Unsafe.Write((p.Addr + keyOffset).ToPointer(), key);
     }
 }
示例#2
0
        // 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));
        }
示例#3
0
 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())));
     }
 }
示例#4
0
        public void initial_count()
        {
            var p = new Pinner();

            Assert.Equal(0, p.PinCount);
            Assert.False(p.IsUnpinnable);
        }
示例#5
0
        /// <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);
        }
示例#8
0
 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);
         }
     }
 }
示例#9
0
        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);
        }
示例#10
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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()));
                }
            }
        }
示例#18
0
        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));
                });
            }
        }
示例#20
0
        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));
                });
            }
        }
示例#21
0
 internal abstract UIntPtr DoPin(UIntPtr address,
                                 Pinner pinner);
示例#22
0
        public void making_no_pins_unpinnable_is_true()
        {
            var p = new Pinner();

            Assert.True(p.MakeUnpinnable());
        }
示例#23
0
        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);
        }