low-level API on synchronized types, which provides programmers with full control over the implementation of non-blocking synchronization semantics. Our main purpose with the low-level API is to provoke a discussion on the trade-off between abstraction versus flexibility.

4.  We illustrate the use of concurrent objects and the alternative, low-level API by several examples.

The remainder of this paper is organized as follows. We summarize the state-of-the-art on memory models and introduce synchronized variables in Sec. \[sec:mm\]. We introduce attributes for specifying memory ordering operations in Sec. \[aspects\]. We specify concurrent objects in Sec. \[nbPO\] and discuss task scheduling in the presence of COs in Sec. \[sched\]. Sec. \[sec:examples\] contains two CO example implementations with varying memory consistency semantics. We discuss our low-level API in Sec. \[API\_sec\]. Sec. \[sec:concl\] contains our conclusions.

This paper is an extension of work that appeared at the Ada-Europe 2018 conference [@BB:2018]. Additional material is confined to two appendices: Appendix \[sec:rationale\] states the design-decisions of our proposed non-blocking synchronization mechanisms. Appendix \[app:examples\] contains further examples.

[The Memory Model\[sec:mm\]]{}

For reasons outlined in Sec. \[sec:intro\], we do not consider the Ada 2012 atomic and volatile types here. Rather, we introduce [*[synchronized]{}*]{} types and variables. Synchronized types provide 