pymembar 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Fabian Krumm
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,4 @@
1
+ include include/membar.h
2
+ include membar/__init__.pyi
3
+ include src/membar.c
4
+ include membarmodule.c
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: pymembar
3
+ Version: 0.1.2
4
+ Summary: Memory barrier utilities for Python - provides wmb, rmb, and fence operations
5
+ Author-email: fwkrumm <fwkrumm@github.com>
6
+ Maintainer-email: fwkrumm <fwkrumm@github.com>
7
+ Project-URL: Homepage, https://github.com/fwkrumm/pymembar
8
+ Project-URL: Repository, https://github.com/fwkrumm/pymembar
9
+ Project-URL: Issues, https://github.com/fwkrumm/pymembar/issues
10
+ Project-URL: Documentation, https://github.com/fwkrumm/pymembar/blob/master/README.md
11
+ Keywords: memory-barriers,concurrency,low-level,synchronization,threading
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: Microsoft :: Windows
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: C
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Topic :: System :: Hardware
21
+ Classifier: Topic :: System :: Operating System
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE.txt
26
+ Dynamic: license-file
27
+
28
+ # Python Memory Barrier (pymembar)
29
+
30
+ Memory barrier utilities for Python - provides low-level memory ordering primitives for concurrent programming. Usually you would not need this in Python due to GIL and generally strong memory ordering on x86/x86_64. However, on weakly-ordered architectures like ARM, memory barriers can be useful for ensuring correct visibility and ordering of memory operations when for example working with shared memory, named semaphores, or lock-free data structures.
31
+
32
+ I used AI (GitHub Copilot) to help generate parts of this README, documentation strings, parts of the core code, the tests, and some configuration files. Please report any inaccuracies or errors you may find.
33
+
34
+
35
+ ## Overview
36
+
37
+ This package provides Python bindings for memory barrier operations, ensuring that memory operations are visible to other processes and threads in the correct order. Memory barriers do not provide synchronization themselves, but rather control the visibility and ordering of memory operations across CPU cores and processes.
38
+
39
+ The package includes three core functions:
40
+
41
+ - `wmb()` - Write memory barrier
42
+ - `rmb()` - Read memory barrier
43
+ - `fence()` - Full memory fence
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ pip install pymembar
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ ### Basic Usage
54
+
55
+ ```python
56
+ import membar
57
+
58
+ # Write memory barrier - ensures all write operations before this point
59
+ # are visible to other processes/threads before any writes after this point
60
+ membar.wmb()
61
+
62
+ # Read memory barrier - ensures all read operations before this point
63
+ # complete before any read operations after this point
64
+ membar.rmb()
65
+
66
+ # Full memory fence - ensures all memory operations before this point
67
+ # are visible to other processes/threads before any operations after this point
68
+ membar.fence()
69
+ ```
70
+
71
+ ### Logging Support
72
+
73
+ You can enable optional logging to see which memory barrier implementation is being used at runtime. This is useful for debugging and understanding which underlying mechanism (C11 atomics, MSVC, GNU atomics, BSD, or compiler barrier) is executing on your platform.
74
+
75
+ **⚠️ Performance Warning:** Enabling logging adds overhead to every memory barrier call (callback check and function call overhead). This can significantly impact performance in tight loops or performance-critical code paths. Logging should primarily be used for debugging and development, and should be disabled (`set_log_callback(None)`) in production code where performance is critical.
76
+
77
+ ```python
78
+ import membar
79
+
80
+ # Enable logging with a custom callback
81
+ def my_logger(message):
82
+ print(f"[MEMBAR] {message}")
83
+
84
+ membar.set_log_callback(my_logger)
85
+
86
+ # Now all barrier calls will log their implementation
87
+ membar.wmb() # Logs: "wmb: using C11 atomic_thread_fence(memory_order_release)"
88
+ membar.fence() # Logs: "fence: using C11 atomic_thread_fence(memory_order_seq_cst)"
89
+
90
+ # You can also use print directly
91
+ membar.set_log_callback(print)
92
+
93
+ # Or integrate with Python's logging module
94
+ import logging
95
+ logging.basicConfig(level=logging.INFO)
96
+ logger = logging.getLogger(__name__)
97
+ membar.set_log_callback(logger.info)
98
+
99
+ # Disable logging by passing None
100
+ membar.set_log_callback(None)
101
+ ```
102
+
103
+ ## When Are Memory Barriers Needed?
104
+
105
+ Memory barriers are primarily needed on weakly-ordered CPU architectures like ARM, where the processor may reorder memory operations for performance optimization. On x86/x86_64 architectures, the strong memory ordering model means that memory barriers are often not strictly necessary for most use cases, as the hardware already provides strong ordering guarantees.
106
+
107
+ However, memory barriers can still be useful on x86 in specific scenarios:
108
+ - When interfacing with memory-mapped I/O
109
+ - In lock-free programming with specific compiler optimizations
110
+ - When precise ordering is critical for correctness
111
+
112
+ **Note:** Most Python applications will not need memory barriers due to the Global Interpreter Lock (GIL) and Python's threading model.
113
+
114
+ ## Requirements
115
+
116
+ - Python 3.10+
117
+ - Compatible with Windows, Linux, and macOS
118
+
119
+ ## Contributing
120
+
121
+ I am not a C expert and would be happy to receive any constructive feedback, suggestions, or contributions to improve this library. Feel free to open issues or submit pull requests on the [GitHub repository](https://github.com/fwkrumm/pymembar).
122
+
123
+ ## Disclaimer
124
+
125
+ Parts of the core code, the tests, this README, and documentation strings were generated with AI assistance.
126
+
127
+ ## Release history
128
+
129
+ - 0.0.1 - Initial release
130
+ - 0.0.2 - Added ARM build support
131
+ - 0.0.3 - Added logging support and multiple synchronization implementations
132
+ - 0.0.4 - Improved logging thread safety and documentation
133
+ - 0.1.0 - Dropped EOL Python versions (3.8, 3.9); minimum is now Python 3.10
134
+ - 0.1.1 - Removed minor-version Python classifiers; Python 3.10+ remains required.
135
+ - 0.1.2 - Added Python 3.15 wheel and source distribution.
136
+
137
+
138
+ ## TODOs
139
+ - Is it possible to write tests for the memory barrier core functionality?
@@ -0,0 +1,112 @@
1
+ # Python Memory Barrier (pymembar)
2
+
3
+ Memory barrier utilities for Python - provides low-level memory ordering primitives for concurrent programming. Usually you would not need this in Python due to GIL and generally strong memory ordering on x86/x86_64. However, on weakly-ordered architectures like ARM, memory barriers can be useful for ensuring correct visibility and ordering of memory operations when for example working with shared memory, named semaphores, or lock-free data structures.
4
+
5
+ I used AI (GitHub Copilot) to help generate parts of this README, documentation strings, parts of the core code, the tests, and some configuration files. Please report any inaccuracies or errors you may find.
6
+
7
+
8
+ ## Overview
9
+
10
+ This package provides Python bindings for memory barrier operations, ensuring that memory operations are visible to other processes and threads in the correct order. Memory barriers do not provide synchronization themselves, but rather control the visibility and ordering of memory operations across CPU cores and processes.
11
+
12
+ The package includes three core functions:
13
+
14
+ - `wmb()` - Write memory barrier
15
+ - `rmb()` - Read memory barrier
16
+ - `fence()` - Full memory fence
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install pymembar
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Basic Usage
27
+
28
+ ```python
29
+ import membar
30
+
31
+ # Write memory barrier - ensures all write operations before this point
32
+ # are visible to other processes/threads before any writes after this point
33
+ membar.wmb()
34
+
35
+ # Read memory barrier - ensures all read operations before this point
36
+ # complete before any read operations after this point
37
+ membar.rmb()
38
+
39
+ # Full memory fence - ensures all memory operations before this point
40
+ # are visible to other processes/threads before any operations after this point
41
+ membar.fence()
42
+ ```
43
+
44
+ ### Logging Support
45
+
46
+ You can enable optional logging to see which memory barrier implementation is being used at runtime. This is useful for debugging and understanding which underlying mechanism (C11 atomics, MSVC, GNU atomics, BSD, or compiler barrier) is executing on your platform.
47
+
48
+ **⚠️ Performance Warning:** Enabling logging adds overhead to every memory barrier call (callback check and function call overhead). This can significantly impact performance in tight loops or performance-critical code paths. Logging should primarily be used for debugging and development, and should be disabled (`set_log_callback(None)`) in production code where performance is critical.
49
+
50
+ ```python
51
+ import membar
52
+
53
+ # Enable logging with a custom callback
54
+ def my_logger(message):
55
+ print(f"[MEMBAR] {message}")
56
+
57
+ membar.set_log_callback(my_logger)
58
+
59
+ # Now all barrier calls will log their implementation
60
+ membar.wmb() # Logs: "wmb: using C11 atomic_thread_fence(memory_order_release)"
61
+ membar.fence() # Logs: "fence: using C11 atomic_thread_fence(memory_order_seq_cst)"
62
+
63
+ # You can also use print directly
64
+ membar.set_log_callback(print)
65
+
66
+ # Or integrate with Python's logging module
67
+ import logging
68
+ logging.basicConfig(level=logging.INFO)
69
+ logger = logging.getLogger(__name__)
70
+ membar.set_log_callback(logger.info)
71
+
72
+ # Disable logging by passing None
73
+ membar.set_log_callback(None)
74
+ ```
75
+
76
+ ## When Are Memory Barriers Needed?
77
+
78
+ Memory barriers are primarily needed on weakly-ordered CPU architectures like ARM, where the processor may reorder memory operations for performance optimization. On x86/x86_64 architectures, the strong memory ordering model means that memory barriers are often not strictly necessary for most use cases, as the hardware already provides strong ordering guarantees.
79
+
80
+ However, memory barriers can still be useful on x86 in specific scenarios:
81
+ - When interfacing with memory-mapped I/O
82
+ - In lock-free programming with specific compiler optimizations
83
+ - When precise ordering is critical for correctness
84
+
85
+ **Note:** Most Python applications will not need memory barriers due to the Global Interpreter Lock (GIL) and Python's threading model.
86
+
87
+ ## Requirements
88
+
89
+ - Python 3.10+
90
+ - Compatible with Windows, Linux, and macOS
91
+
92
+ ## Contributing
93
+
94
+ I am not a C expert and would be happy to receive any constructive feedback, suggestions, or contributions to improve this library. Feel free to open issues or submit pull requests on the [GitHub repository](https://github.com/fwkrumm/pymembar).
95
+
96
+ ## Disclaimer
97
+
98
+ Parts of the core code, the tests, this README, and documentation strings were generated with AI assistance.
99
+
100
+ ## Release history
101
+
102
+ - 0.0.1 - Initial release
103
+ - 0.0.2 - Added ARM build support
104
+ - 0.0.3 - Added logging support and multiple synchronization implementations
105
+ - 0.0.4 - Improved logging thread safety and documentation
106
+ - 0.1.0 - Dropped EOL Python versions (3.8, 3.9); minimum is now Python 3.10
107
+ - 0.1.1 - Removed minor-version Python classifiers; Python 3.10+ remains required.
108
+ - 0.1.2 - Added Python 3.15 wheel and source distribution.
109
+
110
+
111
+ ## TODOs
112
+ - Is it possible to write tests for the memory barrier core functionality?
@@ -0,0 +1,46 @@
1
+ // membar.h
2
+ #pragma once
3
+
4
+ #ifdef _WIN32
5
+ #define MEMBAR_EXPORT __declspec(dllexport)
6
+ #else
7
+ #define MEMBAR_EXPORT
8
+ #endif
9
+
10
+ #ifdef __cplusplus
11
+ extern "C" {
12
+ #endif
13
+
14
+ /**
15
+ * write memory barrier
16
+ * ensures that all previous memory writes are visible before any subsequent writes
17
+ */
18
+ MEMBAR_EXPORT void membar_wmb(void);
19
+
20
+ /**
21
+ * read memory barrier
22
+ * ensures that all previous memory reads are completed before any subsequent reads
23
+ */
24
+ MEMBAR_EXPORT void membar_rmb(void);
25
+
26
+ /**
27
+ * full fence (both read and write)
28
+ * provides sequential consistency across memory operations
29
+ */
30
+ MEMBAR_EXPORT void membar_fence(void);
31
+
32
+ /**
33
+ * logging callback function type
34
+ * @param message - the log message to output
35
+ */
36
+ typedef void (*membar_log_callback)(const char* message);
37
+
38
+ /**
39
+ * set optional logging callback
40
+ * @param callback - function to call for logging, or NULL to disable logging
41
+ */
42
+ MEMBAR_EXPORT void membar_set_log_callback(membar_log_callback callback);
43
+
44
+ #ifdef __cplusplus
45
+ }
46
+ #endif
@@ -0,0 +1,11 @@
1
+ """Memory barrier utilities: wmb, rmb, and fence operations."""
2
+ # pylint: disable=duplicate-code
3
+ try:
4
+ from ._membar import wmb, rmb, fence, set_log_callback # Import from private C extension
5
+ __all__ = ['wmb', 'rmb', 'fence', 'set_log_callback']
6
+ except ImportError as e:
7
+ raise ImportError(f"Could not import C extension module: {e}") from e
8
+
9
+ # do NOT alter the following line in any way EXCEPT changing
10
+ # the version number. no comments, no rename, whatsoever
11
+ __version__ = "0.1.2"
@@ -0,0 +1,57 @@
1
+ """
2
+ Type stubs for membar module - Memory barrier utilities for Python
3
+ """
4
+ from typing import Optional, Callable
5
+
6
+ def wmb() -> None:
7
+ """
8
+ Write memory barrier.
9
+
10
+ Ensures that all write operations issued before this barrier
11
+ are completed before any write operations issued after this barrier.
12
+ """
13
+ ...
14
+
15
+ def rmb() -> None:
16
+ """
17
+ Read memory barrier.
18
+
19
+ Ensures that all read operations issued before this barrier
20
+ are completed before any read operations issued after this barrier.
21
+ """
22
+ ...
23
+
24
+ def fence() -> None:
25
+ """
26
+ Full memory fence.
27
+
28
+ Ensures that all memory operations (both reads and writes) issued before
29
+ this barrier are completed before any memory operations issued after this barrier.
30
+ """
31
+ ...
32
+
33
+ def set_log_callback(callback: Optional[Callable[[str], None]]) -> None:
34
+ """
35
+ Set optional logging callback.
36
+
37
+ Args:
38
+ callback: A callable that takes a string message, or None to disable logging.
39
+ The callback will be invoked whenever a memory barrier function is called,
40
+ with information about which implementation is being used.
41
+
42
+ Example:
43
+ >>> import membar
44
+ >>> membar.set_log_callback(print)
45
+ >>> membar.wmb() # will log which implementation is used
46
+ >>> membar.set_log_callback(None) # disable logging
47
+
48
+ Or use a custom logger:
49
+ >>> import logging
50
+ >>> logger = logging.getLogger("membar_logger")
51
+ >>> membar.set_log_callback(logger.info) # Use logger.info (can also use .debug, .warning, etc.)
52
+ >>> membar.rmb() # logs via the logger
53
+ >>> membar.set_log_callback(None) # disable logging
54
+ """
55
+ ...
56
+
57
+ __all__ = ['wmb', 'rmb', 'fence', 'set_log_callback']
File without changes