|
| 1 | +## PostgreSQL 17 preview - 引入读写原子操作函数接口with full barrier semantics |
| 2 | + |
| 3 | +### 作者 |
| 4 | +digoal |
| 5 | + |
| 6 | +### 日期 |
| 7 | +2024-03-02 |
| 8 | + |
| 9 | +### 标签 |
| 10 | +PostgreSQL , PolarDB , DuckDB , atomic , 原子操作 , 内存屏障 |
| 11 | + |
| 12 | +---- |
| 13 | + |
| 14 | +## 背景 |
| 15 | +https://blog.csdn.net/gp_community/article/details/124636303 |
| 16 | + |
| 17 | +https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bd5132db558b6c8d11eb838be81e2177a95c7388 |
| 18 | +``` |
| 19 | +Introduce atomic read/write functions with full barrier semantics. |
| 20 | + |
| 21 | +author Nathan Bossart <[email protected]> |
| 22 | +Thu, 29 Feb 2024 16:00:44 +0000 (10:00 -0600) |
| 23 | +committer Nathan Bossart <[email protected]> |
| 24 | +Thu, 29 Feb 2024 16:00:44 +0000 (10:00 -0600) |
| 25 | +commit bd5132db558b6c8d11eb838be81e2177a95c7388 |
| 26 | +tree c27f73a66003401092c363a65dae5f88e568af2d tree |
| 27 | +parent 5f2e179bd31e5f5803005101eb12a8d7bf8db8f3 commit | diff |
| 28 | + |
| 29 | +Introduce atomic read/write functions with full barrier semantics. |
| 30 | + |
| 31 | +Writing correct code using atomic variables is often difficult due |
| 32 | +to the memory barrier semantics (or lack thereof) of the underlying |
| 33 | +operations. This commit introduces atomic read/write functions |
| 34 | +with full barrier semantics to ease this cognitive load. For |
| 35 | +example, some spinlocks protect a single value, and these new |
| 36 | +functions make it easy to convert the value to an atomic variable |
| 37 | +(thus eliminating the need for the spinlock) without modifying the |
| 38 | +barrier semantics previously provided by the spinlock. Since these |
| 39 | +functions may be less performant than the other atomic reads and |
| 40 | +writes, they are not suitable for every use-case. However, using a |
| 41 | +single atomic operation with full barrier semantics may be more |
| 42 | +performant in cases where a separate explicit barrier would |
| 43 | +otherwise be required. |
| 44 | + |
| 45 | +The base implementations for these new functions are atomic |
| 46 | +exchanges (for writes) and atomic fetch/adds with 0 (for reads). |
| 47 | +These implementations can be overwritten with better architecture- |
| 48 | +specific versions as they are discovered. |
| 49 | + |
| 50 | +This commit leaves converting existing code to use these new |
| 51 | +functions as a future exercise. |
| 52 | + |
| 53 | +Reviewed-by: Andres Freund, Yong Li, Jeff Davis |
| 54 | +Discussion: https://postgr.es/m/20231110205128.GB1315705%40nathanxps13 |
| 55 | +``` |
| 56 | + |
| 57 | +src/include/port/atomics.h |
| 58 | +``` |
| 59 | ++/* |
| 60 | ++ * pg_atomic_read_membarrier_u32 - read with barrier semantics. |
| 61 | ++ * |
| 62 | ++ * This read is guaranteed to return the current value, provided that the value |
| 63 | ++ * is only ever updated via operations with barrier semantics, such as |
| 64 | ++ * pg_atomic_compare_exchange_u32() and pg_atomic_write_membarrier_u32(). |
| 65 | ++ * While this may be less performant than pg_atomic_read_u32(), it may be |
| 66 | ++ * easier to reason about correctness with this function in less performance- |
| 67 | ++ * sensitive code. |
| 68 | ++ * |
| 69 | ++ * Full barrier semantics. |
| 70 | ++ */ |
| 71 | ++static inline uint32 |
| 72 | ++pg_atomic_read_membarrier_u32(volatile pg_atomic_uint32 *ptr) |
| 73 | ++{ |
| 74 | ++ AssertPointerAlignment(ptr, 4); |
| 75 | ++ |
| 76 | ++ return pg_atomic_read_membarrier_u32_impl(ptr); |
| 77 | ++} |
| 78 | ++ |
| 79 | + /* |
| 80 | + * pg_atomic_write_u32 - write to atomic variable. |
| 81 | + * |
| 82 | +@@ -274,6 +294,26 @@ pg_atomic_unlocked_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val) |
| 83 | + pg_atomic_unlocked_write_u32_impl(ptr, val); |
| 84 | + } |
| 85 | + |
| 86 | ++/* |
| 87 | ++ * pg_atomic_write_membarrier_u32 - write with barrier semantics. |
| 88 | ++ * |
| 89 | ++ * The write is guaranteed to succeed as a whole, i.e., it's not possible to |
| 90 | ++ * observe a partial write for any reader. Note that this correctly interacts |
| 91 | ++ * with both pg_atomic_compare_exchange_u32() and |
| 92 | ++ * pg_atomic_read_membarrier_u32(). While this may be less performant than |
| 93 | ++ * pg_atomic_write_u32(), it may be easier to reason about correctness with |
| 94 | ++ * this function in less performance-sensitive code. |
| 95 | ++ * |
| 96 | ++ * Full barrier semantics. |
| 97 | ++ */ |
| 98 | ++static inline void |
| 99 | ++pg_atomic_write_membarrier_u32(volatile pg_atomic_uint32 *ptr, uint32 val) |
| 100 | ++{ |
| 101 | ++ AssertPointerAlignment(ptr, 4); |
| 102 | ++ |
| 103 | ++ pg_atomic_write_membarrier_u32_impl(ptr, val); |
| 104 | ++} |
| 105 | ++ |
| 106 | + /* |
| 107 | + * pg_atomic_exchange_u32 - exchange newval with current value |
| 108 | + * |
| 109 | +@@ -427,6 +467,15 @@ pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr) |
| 110 | + return pg_atomic_read_u64_impl(ptr); |
| 111 | + } |
| 112 | + |
| 113 | ++static inline uint64 |
| 114 | ++pg_atomic_read_membarrier_u64(volatile pg_atomic_uint64 *ptr) |
| 115 | ++{ |
| 116 | ++#ifndef PG_HAVE_ATOMIC_U64_SIMULATION |
| 117 | ++ AssertPointerAlignment(ptr, 8); |
| 118 | ++#endif |
| 119 | ++ return pg_atomic_read_membarrier_u64_impl(ptr); |
| 120 | ++} |
| 121 | ++ |
| 122 | + static inline void |
| 123 | + pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val) |
| 124 | + { |
| 125 | +@@ -436,6 +485,15 @@ pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val) |
| 126 | + pg_atomic_write_u64_impl(ptr, val); |
| 127 | + } |
| 128 | + |
| 129 | ++static inline void |
| 130 | ++pg_atomic_write_membarrier_u64(volatile pg_atomic_uint64 *ptr, uint64 val) |
| 131 | ++{ |
| 132 | ++#ifndef PG_HAVE_ATOMIC_U64_SIMULATION |
| 133 | ++ AssertPointerAlignment(ptr, 8); |
| 134 | ++#endif |
| 135 | ++ pg_atomic_write_membarrier_u64_impl(ptr, val); |
| 136 | ++} |
| 137 | ++ |
| 138 | + static inline uint64 |
| 139 | + pg_atomic_exchange_u64(volatile pg_atomic_uin |
| 140 | +``` |
| 141 | + |
| 142 | + |
| 143 | +#### [期望 PostgreSQL|开源PolarDB 增加什么功能?](https://github.com/digoal/blog/issues/76 "269ac3d1c492e938c0191101c7238216") |
| 144 | + |
| 145 | + |
| 146 | +#### [PolarDB 开源数据库](https://openpolardb.com/home "57258f76c37864c6e6d23383d05714ea") |
| 147 | + |
| 148 | + |
| 149 | +#### [PolarDB 学习图谱](https://www.aliyun.com/database/openpolardb/activity "8642f60e04ed0c814bf9cb9677976bd4") |
| 150 | + |
| 151 | + |
| 152 | +#### [购买PolarDB云服务折扣活动进行中, 55元起](https://www.aliyun.com/activity/new/polardb-yunparter?userCode=bsb3t4al "e0495c413bedacabb75ff1e880be465a") |
| 153 | + |
| 154 | + |
| 155 | +#### [PostgreSQL 解决方案集合](../201706/20170601_02.md "40cff096e9ed7122c512b35d8561d9c8") |
| 156 | + |
| 157 | + |
| 158 | +#### [德哥 / digoal's Github - 公益是一辈子的事.](https://github.com/digoal/blog/blob/master/README.md "22709685feb7cab07d30f30387f0a9ae") |
| 159 | + |
| 160 | + |
| 161 | +#### [About 德哥](https://github.com/digoal/blog/blob/master/me/readme.md "a37735981e7704886ffd590565582dd0") |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | + |
0 commit comments