Пример #1
0
        private uint getBufferCount(BufferContext context)
        {
            var space = new uint[1];

            vmerblock(space, context.Counter, 1);

            return(space[0]);
        }
Пример #2
0
        private ValueTask <FlushResult> writeToPipeAsync(BufferContext context, CancellationToken stoppingToken)
        {
            vmerblock(context.Buffer, context.Start, (uint)context.Buffer.Length);

            Buffer.BlockCopy(context.Buffer, 0, context.ByteBuffer, 0, context.ByteBuffer.Length);

            return(innerPipe.Writer.WriteAsync(context.ByteBuffer, stoppingToken));
        }
Пример #3
0
        public static IBufferCollection AddBuffer(this IBufferCollection buffers, Action <BufferContext> configure)
        {
            var bc = new BufferContext();

            configure(bc);

            buffers.Add(bc);

            return(buffers);
        }
Пример #4
0
        private async ValueTask <FlushResult> nextBufferAsync(BufferContext context, CancellationToken stoppingToken)
        {
            context.Attempts = 0;
            var  needsToBeFaster = false;
            uint count           = 0;
            ValueTask <FlushResult> result;

            do
            {
                // Wait an appropriate amount of time until attempting to poll the buffer
                await Task.Delay(context.WaitTime);

                // get the current state of the counter
                count = getBufferCount(context);
                context.Attempts++;

                // if count is larger than the previous count, there is new data to be read
                if (count > context.PreviousCount)
                {
                    // read the buffer and send to the pipe
                    result = writeToPipeAsync(context, stoppingToken);

                    // if the difference between the previous and current count is >1
                    // 1 or more whole buffers were missed and the next wait time needs to be
                    // smaller.
                    if (count > context.PreviousCount + 1)
                    {
                        needsToBeFaster = true;
                    }

                    // update the previous count
                    context.PreviousCount = count;

                    break;
                }
            } while (true);

            // adjustments to the wait time are made below

            if (context.Attempts > context.AcceptableMaxAttempts)
            {
                // WaitTime is too small, need to increment it (frequency is too fast - slow it down)

                if (context.PreviousWaitTime == WaitTimeState.TooSmall)
                {
                    // the previous buffer read was too fast as well, so increment the wait time by alot
                    context.WaitTime *= 2;
                }
                else
                {
                    // increment the wait time by 5 ms (might change??)
                    context.WaitTime += 5;                     //(context.WaitTime / 2);
                }

                // update for the next buffer read that this one was too quick
                context.PreviousWaitTime = WaitTimeState.TooSmall;
            }
            else if (needsToBeFaster || context.Attempts < context.AcceptableMinAttempts)
            {
                // WaitTime is too large, need to decrement it (frequency is too slow - speed it up)

                if (context.PreviousWaitTime == WaitTimeState.TooLarge)
                {
                    // the previous buffer read was too slow as well, so decrement the wait time by alot
                    context.WaitTime /= 2;
                }
                else
                {
                    // decrement the wait time by 5 ms (might change??)
                    context.WaitTime -= 5;                     //(context.WaitTime / 2);
                }

                // update for the next buffer read that this previous read was too slow
                context.PreviousWaitTime = WaitTimeState.TooLarge;
            }
            else
            {
                context.PreviousWaitTime = WaitTimeState.JustRight;
            }

            return(await result);
        }