In the course of the project, we have made significant breakthroughs in all three aspects of the project.
First, we have developed a formal model of Intel-x86's consistency and persistency semantics, that involved formalizing advanced architectural features, which were seldomly used prior to the advent of NVM, that enable programmers to bypass the usual cache coherence mechanisms provided by the architecture in order to gain a more predicable persistency semantics and/or higher performance in specific scenarios (e.g. when some data is accessed only once.)
Second, we have developed a framework for specifying the correctness of persistent libraries, such as persistent sets, and a proof technique for establishing one of the most common correctness conditions for such libraries ("durable linearizability"). The crux of our technique is to reuse an existing correctness proof for a version of the abstraction without the persistency guarantees and only prove that the additional code relevant for persistency is actually sufficient for establishing the property of interest.
Third, we have developed a testing infrastructure for testing the persistency semantics of CPU implementations, and have applied it to Intel-x86 and Arm processors. Unfortunately, we were not able to validate the purported persistency semantics of the Intel processors due to their use of a proprietary interface. The Arm processors we tried did not provide any persistency guarantees due to a loophole in the Arm specification/
Finally, we have made several contributions concerning the automated verification ("model checking") of concurrent and persistent programs. For instance, we have developed TruSt, a first truly stateless model checking algorithm that employs optimal dynamic partial order reduction and is parametric in the choice of concistency/persistency model. As such, it can thus be applied directly on implementations of higher-level persistent data structures. In follow up work, we have considered combing TruSt with preemption bounding, a technique for greatly enhancing the scalability of model checking at the expense of losing completeness. Besides such enumerative verification approaches, we have also applied SMT-based model checking approaches to verify persistency invariants of Px86 programs, but have noticed that the enumerative approaches tend to work better for the verification of persistent programs.