Race condition for grammar-declared NTAs in concurrent mode

Issue #291 resolved
Jesper Öqvist
created an issue

A race condition in the generated concurrent evaluation code for grammar-declared NTAs causes separate nodes for the same attribute to become visible.

This is caused by multiple threads being able to call setChild() before updating the memoized attribute value. Moving the setChild() call after memoization can ensure that only one attribute value is visible but then a new problem is to safely read the child node if rewrites are enabled.

The following snippet of generated code illustrates the issue:

        public C getC() {
                ...
                C _result = getC_compute();
                C _value = _result;
/* -----> */    setChild(_result, getCChildPosition());
                if (!getC_value.compareAndSet(AttributeValue.NONE, _value)) {
                        _result = (C) getC_value.get();
                }
                state().leaveLazyAttribute();
                C node = (C) this.getChild(getCChildPosition());
                return node;
        }

The fix for multiple child references:

        public C getC() {
                ...
                C _result = getC_compute();
                C _value = _result;
/* -----> */    _result.setParent(this);
                if (!getC_value.compareAndSet(AttributeValue.NONE, _value)) {
                        _result = (C) getC_value.get();
                } else {
/* -----> */            setChild(_result, getCChildPosition());
                }
                state().leaveLazyAttribute();
                C node = (C) this.getChild(getCChildPosition());
                return node;
        }

Comments (2)

  1. Log in to comment