Skip to content

Instantly share code, notes, and snippets.

View StephenCleary's full-sized avatar

Stephen Cleary StephenCleary

View GitHub Profile
@StephenCleary
StephenCleary / Queue.cs
Last active April 13, 2024 18:37
Some types from Purely Functional Data Structures
public readonly record struct Queue<T>(int FrontCount, Stream<T> Front, int RearCount, Stream<T> Rear)
{
// val empty = Queue (0, $Nil, 0, $Nil)
public static Queue<T> Empty { get; } = new(0, Stream<T>.Empty, 0, Stream<T>.Empty);
// fun isEmpty (lenf, _, _, _) = (lenf = 0)
public bool IsEmpty => FrontCount == 0;
// fun snoc ((lenf, f, lenr, r), x) = check (lenf, f, lenr+1, $Cons (x, r))
public Queue<T> Snoc(T item) => (this with { RearCount = RearCount + 1, Rear = new(item, Rear) }).Check();
@StephenCleary
StephenCleary / CustomBoundedChannel.cs
Created October 23, 2023 20:05
A System.Threading.Channel<T> that allows custom bounds (more complex than counting items)
using System.Threading.Channels;
using Nito.AsyncEx;
// All members must be safe to call while under lock.
public interface ICustomBounds<in T>
{
bool IsEmpty { get; }
bool IsFull { get; }
void Add(T item);
void Subtract(T item);
@StephenCleary
StephenCleary / memory_docs_samples.md
Created September 14, 2023 12:41 — forked from GrabYourPitchforks/memory_docs_samples.md
Memory<T> API documentation and samples

Memory<T> API documentation and samples

This document describes the APIs of Memory<T>, IMemoryOwner<T>, and MemoryManager<T> and their relationships to each other.

See also the Memory<T> usage guidelines document for background information.

First, a brief summary of the basic types

  • Memory<T> is the basic type that represents a contiguous buffer. This type is a struct, which means that developers cannot subclass it and override the implementation. The basic implementation of the type is aware of contigious memory buffers backed by T[] and System.String (in the case of ReadOnlyMemory<char>).
@StephenCleary
StephenCleary / AutoResetCancellationTokenSource.cs
Created September 14, 2023 12:30
Resettable CTSs using InterlockedState
using System.Threading;
/// <summary>
/// A <see cref="CancellationTokenSource"/> that resets itself to uncanceled after <see cref="Cancel"/> is called.
/// </summary>
public sealed class AutoResetCancellationTokenSource
{
/// <summary>
/// Cancels any tokens previously returned from <see cref="Token"/>, and resets this instance to an uncancelled state.
/// </summary>
@StephenCleary
StephenCleary / InterlockedState.cs
Last active October 2, 2023 02:50
Helper methods for working with interlocked state
using System;
using System.Threading;
/// <summary>
/// Interlocked helper methods.
/// </summary>
public static class InterlockedState
{
/// <summary>
/// Executes a state transition from one state to another.
@StephenCleary
StephenCleary / DynamicTaskWhenAll.cs
Created March 25, 2023 21:36
Dynamic Task.WhenAll
// Developed as part of https://github.com/StephenCleary/StructuredConcurrency but wasn't necessary for that project.
/// <summary>
/// Similar to <see cref="Task.WhenAll{TResult}(Task{TResult}[])"/>, but allowing any number of tasks to be added, even after waiting has begun.
/// At least one task must be added, or else the <see cref="Task"/> will never complete.
/// </summary>
/// <typeparam name="TResult">The type of the result of the tasks.</typeparam>
public sealed class DynamicTaskWhenAll<TResult>
{
private readonly TaskCompletionSource<IReadOnlyList<TResult>> _taskCompletionSource = new();
@StephenCleary
StephenCleary / Moved.md
Last active March 30, 2023 01:20
TaskGroup: Structured Concurrency for C#
@StephenCleary
StephenCleary / TaskDictionary.cs
Last active January 14, 2023 19:09
A concurrent dictionary of tasks that can be resolved by key.
public sealed class TaskDictionary<TRequest, TResult>
where TRequest : notnull
{
public TaskDictionary(IEqualityComparer<TRequest>? comparer = null)
{
_dictionary = new(comparer);
}
public Task<TResult> GetOrAdd(TRequest request)
{
@StephenCleary
StephenCleary / CancellationTokenSourceCache.cs
Last active September 6, 2022 02:29
Cache for reusing CTS instances.
using System.Collections.Concurrent;
using System.Diagnostics;
using Nito.Disposables;
/// <summary>
/// A cache of uncanceled <see cref="CancellationTokenSource"/> instances.
/// </summary>
public sealed class CancellationTokenSourceCache
{
private readonly ConcurrentBag<CancellationTokenSource> _sources = new();
@StephenCleary
StephenCleary / AlignedMemoryManager.cs
Created September 3, 2022 14:45
IMemoryOwner for aligned memory
public abstract class AlignedMemoryManager : MemoryManager<byte>
{
// Note: No finalizer; this will deliberately leak memory if never disposed.
// https://gist.github.com/GrabYourPitchforks/8efb15abbd90bc5b128f64981766e834#implementation-notes-when-subclassing-memorymanagert
private IntPtr _pointer;
protected static unsafe IntPtr Allocate(nuint byteCount, nuint alignment) => (IntPtr)NativeMemory.AlignedAlloc(byteCount, alignment);
public override unsafe Span<byte> GetSpan() => new((void*)_pointer, ByteCount);