Skip to content

Commit

Permalink
Merge pull request #302 from kriszyp/arm-memory-safety
Browse files Browse the repository at this point in the history
Safer Atomic assignment on ARM
  • Loading branch information
kriszyp authored Aug 20, 2024
2 parents 9289b4d + fb8b9b7 commit f74c02d
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lmdb",
"author": "Kris Zyp",
"version": "3.0.13",
"version": "3.0.14",
"description": "Simple, efficient, scalable, high-performance LMDB interface",
"license": "MIT",
"repository": {
Expand Down
18 changes: 13 additions & 5 deletions write.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SYNC_PROMISE_SUCCESS.result = true;
SYNC_PROMISE_FAIL.isSync = true;
SYNC_PROMISE_FAIL.result = false;
const PROMISE_SUCCESS = Promise.resolve(true);
const arch = process.arch;
export const ABORT = 4.452694326329068e-106; // random/unguessable numbers, which work across module/versions and native
export const IF_EXISTS = 3.542694326329068e-103;
const CALLBACK_THREW = {};
Expand Down Expand Up @@ -355,12 +356,19 @@ export function addWriteMethods(

return (callback) => {
if (writtenBatchDepth) {
// if we are in a batch, the transaction can't close, so we do the faster,
// If we are in a batch, the transaction can't close, so we do the faster,
// but non-deterministic updates, knowing that the write thread can
// just poll for the status change if we miss a status update
writeStatus = uint32[flagPosition];
uint32[flagPosition] = flags;
//writeStatus = Atomics.or(uint32, flagPosition, flags)
// just poll for the status change if we miss a status update.
// That is, if we are on x64 architecture...
if (arch === 'x64') {
writeStatus = uint32[flagPosition];
uint32[flagPosition] = flags;
} else {
// However, on ARM processors, apparently more radical memory reordering can occur
// so we need to use the slower atomic operation to ensure that a memory barrier is set
// and that the value pointer is actually written before the flag is updated
writeStatus = Atomics.or(uint32, flagPosition, flags);
}
if (writeBatchStart && !writeStatus) {
outstandingBatchCount += 1 + (valueSize >> 12);
if (outstandingBatchCount > batchStartThreshold) {
Expand Down

0 comments on commit f74c02d

Please sign in to comment.