Use atomic operations for updating syntax tree reference counts

Co-Authored-By: Rick Winfrey <rewinfrey@github.com>
This commit is contained in:
Max Brunsfeld 2018-05-09 17:30:13 -07:00
parent 666dfb76d2
commit 78d158899e
3 changed files with 34 additions and 4 deletions

30
src/runtime/atomic.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef RUNTIME_ATOMIC_H_
#define RUNTIME_ATOMIC_H_
#include <stdint.h>
#ifdef _WIN32
#include <windows.h>
static inline uint32_t atomic_inc(volatile uint32_t *p) {
return InterlockedIncrement(p);
}
static inline uint32_t atomic_dec(volatile uint32_t *p) {
return InterlockedDecrement(p);
}
#else
static inline uint32_t atomic_inc(volatile uint32_t *p) {
return __sync_add_and_fetch(p, 1u);
}
static inline uint32_t atomic_dec(volatile uint32_t *p) {
return __sync_sub_and_fetch(p, 1u);
}
#endif
#endif // RUNTIME_ATOMIC_H_

View file

@ -5,6 +5,7 @@
#include <string.h>
#include <stdio.h>
#include "runtime/alloc.h"
#include "runtime/atomic.h"
#include "runtime/tree.h"
#include "runtime/length.h"
#include "runtime/language.h"
@ -356,7 +357,7 @@ Tree *ts_tree_make_missing_leaf(TreePool *pool, TSSymbol symbol, const TSLanguag
void ts_tree_retain(Tree *self) {
assert(self->ref_count > 0);
self->ref_count++;
atomic_inc(&self->ref_count);
assert(self->ref_count != 0);
}
@ -366,8 +367,7 @@ void ts_tree_release(TreePool *pool, Tree *self) {
while (pool->tree_stack.size > 0) {
Tree *tree = array_pop(&pool->tree_stack);
assert(tree->ref_count > 0);
tree->ref_count--;
if (tree->ref_count == 0) {
if (atomic_dec(&tree->ref_count) == 0) {
if (tree->children.size > 0) {
for (uint32_t i = 0; i < tree->children.size; i++) {
array_push(&pool->tree_stack, tree->children.contents[i]);

View file

@ -29,7 +29,7 @@ typedef Array(Tree *) TreeArray;
struct Tree {
Length padding;
Length size;
uint32_t ref_count;
volatile uint32_t ref_count;
uint32_t bytes_scanned;
uint32_t error_cost;
uint32_t node_count;