Skip to content
This repository was archived by the owner on Aug 16, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
78bd293
Updating nuget packages and the benchmarks
prezaei Oct 3, 2021
ae1f80a
Updating the benchmark values
prezaei Oct 3, 2021
bf65e28
One fix
prezaei Oct 3, 2021
4c82b77
Minor docs update
prezaei Oct 5, 2021
fa482b9
Code cleanup
prezaei Oct 15, 2021
c5bca51
Merge pull request #12 from cloudtoid/pedramr/improvements
prezaei Oct 15, 2021
f9fdd21
Adding support for .NET 6 and updating all depende
prezaei Apr 5, 2022
e2768b0
REDME Update
prezaei Apr 5, 2022
c6530dc
Added support for .NET 7 and removed suport for .NET 5
prezaei Nov 19, 2022
1ca167c
Few more updates
prezaei Nov 19, 2022
f9795f1
minor readme update
prezaei Nov 19, 2022
9b5cf76
Fixing Ubuntu - System.DllNotFoundException: Unable to load shared li…
prezaei Nov 19, 2022
497bd68
Update WSL bench marks
prezaei Nov 19, 2022
0cd52d1
Fix for github issue #15
prezaei Nov 20, 2022
17e841f
Added more tests
prezaei Nov 21, 2022
977bdde
one more fix
prezaei Nov 22, 2022
1f1c6a8
clean up
prezaei Nov 22, 2022
e06c13a
More clean up
prezaei Nov 22, 2022
35b3c47
update build scripts
prezaei Nov 22, 2022
e5521cd
Merge pull request #16 from cloudtoid/pedramr/overflow-bug-fix
prezaei Nov 22, 2022
28e5193
A few renames
prezaei Nov 22, 2022
8f52ef5
a left file
prezaei Nov 22, 2022
c453e56
A start!
prezaei Nov 22, 2022
f064a0d
Decouple queue message capacity from the size of he memory mapped file
prezaei Nov 24, 2022
b79ff30
Made some progress on V2
prezaei Nov 25, 2022
9a6631c
More updates
prezaei Nov 26, 2022
a0cc1ef
Updating the version number to a pre-release v
prezaei Nov 26, 2022
cfd0e22
Removing some random left over test code
prezaei Nov 26, 2022
8a4b91e
Updating the publisher sample
prezaei Nov 26, 2022
4a68638
minor change
prezaei Nov 26, 2022
d380d4f
Capacity
prezaei Nov 26, 2022
d8236a5
Queue disk size
prezaei Nov 26, 2022
5abdddf
change of comment
prezaei Nov 26, 2022
30a72fd
one more rename
prezaei Nov 26, 2022
2f18a55
space
prezaei Nov 26, 2022
4090324
Merge pull request #17 from cloudtoid/v2
prezaei Nov 26, 2022
46ff224
Move to .NET 8
prezaei Sep 25, 2024
3e3d631
one more
prezaei Sep 25, 2024
1cef822
some renames
prezaei Sep 25, 2024
ddf02e4
remove files
prezaei Sep 26, 2024
00e1860
one more
prezaei Sep 26, 2024
4b40da1
package updates
prezaei Jan 11, 2025
e8a381d
one more
prezaei Jan 11, 2025
d4c44a6
Fix macos
prezaei Jan 11, 2025
69cb3be
Updating benchmarks for macos
prezaei Jan 12, 2025
70ccce3
one more
prezaei Jan 12, 2025
7e72f9d
one more
prezaei Jan 12, 2025
66246a1
readme update
prezaei Jan 12, 2025
0b8b836
Refactor
prezaei Jan 12, 2025
1886c48
one more
prezaei Jan 12, 2025
b908537
more
prezaei Jan 12, 2025
edc70d5
one more
prezaei Jan 12, 2025
4005dd3
one more
prezaei Jan 12, 2025
0c9647b
one more
prezaei Jan 12, 2025
c7922ee
one more
prezaei Jan 12, 2025
d4fb234
one more
prezaei Jan 12, 2025
bbb4e99
one more
prezaei Jan 12, 2025
e14646f
one more
prezaei Jan 12, 2025
cc28948
one more
prezaei Jan 12, 2025
4e17ad1
Merge pull request #21 from cloudtoid/refactor
prezaei Jan 12, 2025
be6a3a6
one more
prezaei Jan 12, 2025
f9dcba0
one more
prezaei Jan 12, 2025
547c530
bug fix
prezaei Jan 12, 2025
81a39e1
solve a possible deadlock
prezaei Jan 12, 2025
644f9cc
Update src/Interprocess.Tests/QueueTests.cs
prezaei Jan 12, 2025
6dfa9b3
Update src/Interprocess.Tests/QueueTests.cs
prezaei Jan 12, 2025
c21b996
Merge pull request #24 from cloudtoid/Deadlock
prezaei Jan 12, 2025
693c70d
using implicit usings
prezaei Jan 12, 2025
d9da9e7
Merge branch 'main' into Deadlock
prezaei Jan 12, 2025
839b6dd
Merge pull request #25 from cloudtoid/Deadlock
prezaei Jan 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,13 @@ jobs:
steps:

- name: Checkout
uses: actions/checkout@v2

- name: Setup .NET Core 3.1.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'

- name: Setup .NET 5.0.x
uses: actions/setup-dotnet@v1
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '5.0.x'

- name: Build - Release
run: dotnet build -c Release src/Interprocess.sln
dotnet-version: |
9.0.x

- name: Test - Debug
- name: Build and Test
run: dotnet test src/Interprocess.sln
19 changes: 6 additions & 13 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,16 @@ jobs:
steps:

- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup .NET Core 3.1.x
uses: actions/setup-dotnet@v1
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '3.1.x'

- name: Setup .NET 5.0.x
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'

- name: Build - Debug
run: dotnet build src/Interprocess.sln
dotnet-version: |
9.0.x

- name: Test - Debug
run: dotnet test --no-build --verbosity=detailed src/Interprocess.sln
run: dotnet test src/Interprocess.sln

- name: Build - Release
run: dotnet build -c Release src/Interprocess.sln
Expand Down
31 changes: 12 additions & 19 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"name": "Publisher Sample",
"type": "dotnet",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/SharedMemory.Tests/bin/Debug/netcoreapp3.1/SharedMemory.Tests.dll",
"args": [],
"cwd": "${workspaceFolder}/src/SharedMemory.Tests",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
"projectPath": "${workspaceFolder}/src/Sample/Publisher/Publisher.csproj"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
"name": "Subscriber Sample",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/src/Sample/Subscriber/Subscriber.csproj"
}
]
}
9 changes: 8 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
{
"cSpell.words": [
"Cloudtoid",
"Diagnoser",
"finalizer",
"Interprocess",
"Kaby",
"Onnx",
"Pedram",
"Posix",
"Rezaei",
"Xeon"
"Roslynator",
"Timespec",
"Xeon",
"Xunit"
]
}
63 changes: 23 additions & 40 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,25 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/SharedMemory.Tests/SharedMemory.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/SharedMemory.Tests/SharedMemory.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/src/SharedMemory.Tests/SharedMemory.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "dotnet",
"args": [
"build",
"${workspaceFolder}/src"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$msCompile"
],
"presentation": {
"reveal": "always",
"panel": "shared"
}
},
]
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 cloudtoid
Copyright (c) 2022 cloudtoid

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
103 changes: 48 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

# Interprocess

[![][WorkflowBadgePublish]][PublishWorkflow] [![License: MIT][LicenseBadge]][License] [![][NuGetBadge]][NuGet] ![][DotNetBadge]
[![Publish Workflow][WorkflowBadgePublish]][PublishWorkflow]
[![Latest NuGet][NuGetBadge]][NuGet]
[![License: MIT][LicenseBadge]][License]
![.NET Platform][DotNetPlatformBadge]

**Cloudtoid Interprocess** is a cross-platform shared memory queue for fast communication between processes ([Interprocess Communication or IPC][IPCWiki]). It uses a shared memory-mapped file for extremely fast and efficient communication between processes and it is used internally by Microsoft.

- [**Fast**](#performance): It is *extremely* fast.
- **Cross-platform**: It supports Windows, and Unix-based operating systems such as Linux, [MacOS][MacOSWiki], and [FreeBSD][FreeBSDOrg].
- [**API**](#Usage): Provides a simple and intuitive API to enqueue/send and dequeue/receive messages.
- **Cross-platform**: It supports Windows, and Unix-based operating systems such as Linux, [macOS][macOSWiki], and [FreeBSD][FreeBSDOrg].
- [**API**](#usage): Provides a simple and intuitive API to enqueue/send and dequeue/receive messages.
- **Multiple publishers and subscribers**: It supports multiple publishers and subscribers to a shared queue.
- [**Efficient**](#performance): Sending and receiving messages is almost heap memory allocation free reducing garbage collections.
- [**Developer**](#Author): Developed by a guy at Microsoft.
- [**Developer**](#author): Developed by a guy at Microsoft.

## NuGet Package

Expand All @@ -21,7 +24,7 @@ The NuGet package for this library is published [here][NuGet].

## Usage

This library supports .NET Core 3.1+ and .NET 5+. It is optimized for .NET dependency injection but can also be used without DI.
This library is optimized for .NET dependency injection but can also be used without DI.

### Usage without DI

Expand Down Expand Up @@ -98,26 +101,19 @@ Please note that you can start multiple publishers and subscribers sending and r

A lot has gone into optimizing the implementation of this library. For instance, it is mostly heap-memory allocation free, reducing the need for garbage collection induced pauses.

**Summary**: In average, enqueuing a message is about `~10 ns` and a full enqueue followed by a dequeue takes roughly `~400 ns` on Windows, `~300 ns` on linux, and `~700 ns`.
**Summary**: A full enqueue followed by a dequeue takes `~250 ns` on Linux, `~650 ns` on macOS, and `~300 ns` on Windows.

**Details**: To benchmark the performance and memory usage, we use [BenchmarkDotNet][BenchmarkOrg] and perform the following runs:

| Method | Description |
|------------------------------------------------ |-------------- |
| Message enqueue | Benchmarks the performance of enqueuing a message. |
| Message enqueue and dequeue | Benchmarks the performance of sending a message to a client and receiving that message. It is inclusive of the duration to enqueue and dequeue a message. |
| Message enqueue and dequeue - no message buffer | Benchmarks the performance of sending a message to a client and receiving that message. It is inclusive of the duration to enqueue and dequeue a message and memory allocation for the received message. |

You can replicate the results by running the following command:

```posh
dotnet run Interprocess.Benchmark.csproj --configuration Release
```

You can also be explicit about the .NET SDK and Runtime(s) versions:

```posh
dotnet run Interprocess.Benchmark.csproj --configuration Release --framework net5.0 --runtimes net5.0 netcoreapp3.1
```sh
dotnet run Interprocess.Benchmark.csproj -c Release
```

---
Expand All @@ -126,78 +122,73 @@ dotnet run Interprocess.Benchmark.csproj --configuration Release --framework net

Host:

```ini
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Xeon CPU E5-1620 v3 3.50GHz, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.201
[Host] : .NET Core 5.0.4, X64 RyuJIT
.NET Core 3.1 : .NET Core 3.1.13, X64 RyuJIT
```text
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
Intel Core i9-10900X CPU 3.70GHz, 1 CPU, 20 logical and 10 physical cores
.NET SDK=6.0.201
[Host] : .NET 6.0.3 (6.0.322.12309), X64 RyuJIT
.NET 6.0 : .NET 6.0.3 (6.0.322.12309), X64 RyuJIT
```

Results:

| Method | Mean (ns) | Error (ns) | StdDev (ns) | Allocated |
|------------------------------------------------ |----------:|-----------:|------------:|----------:|
| Message enqueue | `7.041`| `0.0753`| `0.0629`| `-` |
| Message enqueue and dequeue | `390.081`| `3.940`| `3.4930`| `-` |
| Message enqueue and dequeue - no message buffer | `375.899`| `3.706`| `3.4664`| `32 B` |
| Message enqueue and dequeue | `305.6`| `5.96`| `6.62`| `-` |
| Message enqueue and dequeue - no message buffer | `311.5`| `5.90`| `9.85`| `32 B` |

---

### On MacOS
### On macOS

Host:

```ini
OS=macOS Catalina 10.15.6
Intel Core i5-8279U CPU 2.40GHz (Coffee Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.401
[Host] : .NET Core 3.1.7, X64 RyuJIT
.NET Core 3.1 : .NET Core 3.1.7, X64 RyuJIT
```text
BenchmarkDotNet v0.14.0, macOS Sequoia 15.2 (24C101) [Darwin 24.2.0]
Apple M3 Max, 1 CPU, 16 logical and 16 physical cores
.NET SDK 9.0.101
[Host] : .NET 9.0.0 (9.0.24.52809), Arm64 RyuJIT AdvSIMD
.NET 9.0 : .NET 9.0.0 (9.0.24.52809), Arm64 RyuJIT AdvSIMD
```

Results:

| Method | Mean (ns) | Error (ns) | StdDev (ns) | Allocated |
|------------------------------------------------ |----------:|-----------:|------------:|----------:|
| Message enqueue | `14.19`| `0.05`| `0.04`| `-`|
| Message enqueue and dequeue | `666.10`| `10.91`| `10.20`| `-`|
| Message enqueue and dequeue - no message buffer | `689.33`| `13.38`| `15.41`| `32 B`|
| Method | Mean (ns) | Error (ns) | StdDev | Gen0 | Allocated |
|-------------------------------------------------- |----------:|-----------:|-------:|---------:|----------:|
| 'Message enqueue and dequeue' | `249.2` | `0.74` | `0.62` | `-` | `-` |
| 'Message enqueue and dequeue - no message buffer' | `252.1` | `4.10` | `3.83` | `0.0038` | `32 B` |

---

### On Ubuntu (through [WSL][WslDoc])

Host:

```ini
BenchmarkDotNet=v0.12.1, OS=ubuntu 20.04
Intel Xeon CPU E5-1620 v3 3.50GHz, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.201
[Host] : .NET Core 5.0.4, X64 RyuJIT
.NET Core 3.1 : .NET Core 3.1.13, X64 RyuJIT
```text
BenchmarkDotNet=v0.13.2, OS=ubuntu 20.04
Intel Core i9-10900X CPU 3.70GHz, 1 CPU, 20 logical and 10 physical cores
.NET SDK=6.0.403
[Host] : .NET 6.0.11 (6.0.1122.52304), X64 RyuJIT AVX2
.NET 6.0 : .NET 6.0.11 (6.0.1122.52304), X64 RyuJIT AVX2
```

Results:

| Method | Mean (ns) | Error (ns) | StdDev (ns) | Allocated |
|------------------------------------------------ |----------:|-----------:|------------:|----------:|
| Message enqueue | `13.89`| `0.102`| `0.080`| `-`|
| Message enqueue and dequeue | `283.55`| `5.592`| `7.839`| `-`|
| Message enqueue and dequeue - no message buffer | `271.17`| `4.355`| `3.400`| `32 B`|
| Message enqueue and dequeue | `169.9`| `3.08`| `4.01`| `-`|
| Message enqueue and dequeue - no message buffer | `179.4`| `1.91`| `1.60`| `32 B`|

## Implementation Notes

This library relies on [Named Semaphores][NamedSemaphoresDoc] To signal the existence of a new message to all message subscribers and to do it across process boundaries. Named semaphores are synchronization constructs accessible across processes.

.NET Core 3.1 and .NET 5 do not support named semaphores on Unix-based OSs (Linux, macOS, etc.). Instead we are using P/Invoke and relying on operating system's POSIX semaphore implementation. ([Linux](src/Interprocess/Semaphore/Linux/Interop.cs) and [MacOS](src/Interprocess/Semaphore/MacOS/Interop.cs) implementations).
.NET currently does not support named semaphores on Unix-based OSs (Linux, macOS, etc.). Instead we are using P/Invoke and relying on operating system's POSIX semaphore implementation. ([Linux](src/Interprocess/Semaphore/Linux/Interop.cs) and [macOS](src/Interprocess/Semaphore/macOS/Interop.cs) implementations).

This implementation will be replaced with [`System.Threading.Semaphore`][SemaphoreDoc] once .NET adds support for named semaphores on all platforms.

## How to Contribute

- Create a branch from `main`.
- Ensure that all tests pass on Windows, Linux, and MacOS.
- Ensure that all tests pass on Windows, Linux, and macOS.
- Keep the code coverage number above 80% by adding new tests or modifying the existing tests.
- Send a pull request.

Expand All @@ -209,21 +200,23 @@ This implementation will be replaced with [`System.Threading.Semaphore`][Semapho

Here are a couple of items that we are working on.

- Create a documentation website
- Create a marketing/documentation website
- Once .NET supports named semaphores on Linux, then start using them.

[Cloudtoid]:https://github.com/cloudtoid
[License]:https://github.com/cloudtoid/interprocess/blob/main/LICENSE
[LicenseBadge]:https://img.shields.io/badge/License-MIT-blue.svg
[WorkflowBadgePublish]:https://github.com/cloudtoid/interprocess/workflows/publish/badge.svg
[PublishWorkflow]:https://github.com/cloudtoid/interprocess/actions/workflows/publish.yml
[NuGetBadge]:https://img.shields.io/nuget/vpre/Cloudtoid.Interprocess
[DotNetBadge]:https://img.shields.io/badge/.net%20core-%3E%203.1.0-blue
[DotNetPlatformBadge]:https://img.shields.io/badge/.net-%3E%209.0-blue
[NuGet]:https://www.nuget.org/packages/Cloudtoid.Interprocess/
[IPCWiki]:https://en.wikipedia.org/wiki/Inter-process_communication
[MacOSWiki]:https://en.wikipedia.org/wiki/MacOS
[macOSWiki]:https://en.wikipedia.org/wiki/macOS
[FreeBSDOrg]:https://www.freebsd.org/
[Wow64Wiki]:https://en.wikipedia.org/wiki/WoW64
[WslDoc]:https://docs.microsoft.com/en-us/windows/wsl/about
[WslDoc]:https://learn.microsoft.com/windows/wsl/about
[BenchmarkOrg]:https://benchmarkdotnet.org/
[SemaphoreDoc]:https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphore
[PedramLinkedIn]:https://www.linkedin.com/in/pedramrezaei/
[NamedSemaphoresDoc]:https://docs.microsoft.com/dotnet/api/system.threading.semaphore#remarks
[SemaphoreDoc]:https://docs.microsoft.com/dotnet/api/system.threading.semaphore
[PedramLinkedIn]:https://www.linkedin.com/in/pedramrezaei/
Loading