Showing preview only (3,797K chars total). Download the full file or copy to clipboard to get everything.
Repository: pramalhe/OneFile
Branch: master
Commit: 49654893f081
Files: 412
Total size: 3.5 MB
Directory structure:
gitextract_33ubg_0h/
├── LICENSE.txt
├── README.md
├── common/
│ ├── HazardEras.hpp
│ ├── HazardPointers.hpp
│ ├── HazardPointersSimQueue.hpp
│ ├── README.md
│ ├── RIStaticPerThread.hpp
│ ├── ThreadRegistry.cpp
│ ├── ThreadRegistry.hpp
│ └── pfences.h
├── datastructures/
│ ├── generic/
│ │ ├── TMHashMap.hpp
│ │ ├── TMLinkedListQueue.hpp
│ │ ├── TMLinkedListSet.hpp
│ │ └── TMRedBlackBST.hpp
│ ├── hashmaps/
│ │ ├── CRWWPSTMResizableHashSet.hpp
│ │ ├── ESTMResizableHashSet.hpp
│ │ ├── OFLFResizableHashSet.hpp
│ │ ├── OFWFResizableHashSet.hpp
│ │ └── TinySTMResizableHashSet.hpp
│ ├── linkedlists/
│ │ ├── CRWWPLinkedListSet.hpp
│ │ ├── ESTMLinkedListSet.hpp
│ │ ├── HazardEras.hpp
│ │ ├── HazardPointers.hpp
│ │ ├── MagedHarrisLinkedListSetHE.hpp
│ │ ├── MagedHarrisLinkedListSetHP.hpp
│ │ ├── OFLFLinkedListSet.hpp
│ │ ├── OFWFLinkedListSet.hpp
│ │ ├── STMLinkedListSet.hpp
│ │ └── TinySTMLinkedListSet.hpp
│ ├── queues/
│ │ ├── CRWWPLinkedListQueue.hpp
│ │ ├── ESTMArrayLinkedListQueue.hpp
│ │ ├── ESTMLinkedListQueue.hpp
│ │ ├── FAAArrayQueue.hpp
│ │ ├── HazardPointers.hpp
│ │ ├── HazardPointersSimQueue.hpp
│ │ ├── LCRQueue.hpp
│ │ ├── MichaelScottQueue.hpp
│ │ ├── OFLFArrayLinkedListQueue.hpp
│ │ ├── OFLFArrayQueue.hpp
│ │ ├── OFLFLinkedListQueue.hpp
│ │ ├── OFWFArrayLinkedListQueue.hpp
│ │ ├── OFWFLinkedListQueue.hpp
│ │ ├── README.md
│ │ ├── SimQueue.hpp
│ │ ├── TinySTMArrayLinkedListQueue.hpp
│ │ ├── TinySTMLinkedListQueue.hpp
│ │ └── TurnQueue.hpp
│ ├── sequential/
│ │ ├── HashSet.hpp
│ │ ├── LinkedListQueue.hpp
│ │ ├── LinkedListSet.hpp
│ │ ├── RedBlackBST.hpp
│ │ ├── SortedArraySet.hpp
│ │ ├── SortedVectorSet.hpp
│ │ └── TreeSet.hpp
│ ├── treemaps/
│ │ ├── ESTMRedBlackTree.hpp
│ │ ├── HazardEras.hpp
│ │ ├── NatarajanTreeHE.hpp
│ │ ├── OFLFRedBlackTree.hpp
│ │ ├── OFWFRedBlackTree.hpp
│ │ └── TinySTMRedBlackTree.hpp
│ ├── trevor_brown_abtree/
│ │ ├── Makefile
│ │ ├── TrevorBrownABTree.hpp
│ │ ├── common/
│ │ │ ├── atomic_ops/
│ │ │ │ ├── atomic_ops/
│ │ │ │ │ ├── generalize-small.h
│ │ │ │ │ ├── generalize.h
│ │ │ │ │ └── sysdeps/
│ │ │ │ │ ├── README
│ │ │ │ │ ├── acquire_release_volatile.h
│ │ │ │ │ ├── aligned_atomic_load_store.h
│ │ │ │ │ ├── all_acquire_release_volatile.h
│ │ │ │ │ ├── all_aligned_atomic_load_store.h
│ │ │ │ │ ├── all_atomic_load_store.h
│ │ │ │ │ ├── ao_t_is_int.h
│ │ │ │ │ ├── armcc/
│ │ │ │ │ │ └── arm_v6.h
│ │ │ │ │ ├── atomic_load_store.h
│ │ │ │ │ ├── char_acquire_release_volatile.h
│ │ │ │ │ ├── char_atomic_load_store.h
│ │ │ │ │ ├── emul_cas.h
│ │ │ │ │ ├── gcc/
│ │ │ │ │ │ ├── alpha.h
│ │ │ │ │ │ ├── arm.h
│ │ │ │ │ │ ├── avr32.h
│ │ │ │ │ │ ├── cris.h
│ │ │ │ │ │ ├── hppa.h
│ │ │ │ │ │ ├── ia64.h
│ │ │ │ │ │ ├── m68k.h
│ │ │ │ │ │ ├── mips.h
│ │ │ │ │ │ ├── powerpc.h
│ │ │ │ │ │ ├── s390.h
│ │ │ │ │ │ ├── sh.h
│ │ │ │ │ │ ├── sparc.h
│ │ │ │ │ │ ├── x86.h
│ │ │ │ │ │ └── x86_64.h
│ │ │ │ │ ├── generic_pthread.h
│ │ │ │ │ ├── hpc/
│ │ │ │ │ │ ├── hppa.h
│ │ │ │ │ │ └── ia64.h
│ │ │ │ │ ├── ibmc/
│ │ │ │ │ │ └── powerpc.h
│ │ │ │ │ ├── icc/
│ │ │ │ │ │ └── ia64.h
│ │ │ │ │ ├── int_acquire_release_volatile.h
│ │ │ │ │ ├── int_aligned_atomic_load_store.h
│ │ │ │ │ ├── int_atomic_load_store.h
│ │ │ │ │ ├── msftc/
│ │ │ │ │ │ ├── arm.h
│ │ │ │ │ │ ├── common32_defs.h
│ │ │ │ │ │ ├── x86.h
│ │ │ │ │ │ └── x86_64.h
│ │ │ │ │ ├── ordered.h
│ │ │ │ │ ├── ordered_except_wr.h
│ │ │ │ │ ├── read_ordered.h
│ │ │ │ │ ├── short_acquire_release_volatile.h
│ │ │ │ │ ├── short_aligned_atomic_load_store.h
│ │ │ │ │ ├── short_atomic_load_store.h
│ │ │ │ │ ├── standard_ao_double_t.h
│ │ │ │ │ ├── sunc/
│ │ │ │ │ │ ├── sparc.h
│ │ │ │ │ │ ├── x86.h
│ │ │ │ │ │ └── x86_64.h
│ │ │ │ │ ├── test_and_set_t_is_ao_t.h
│ │ │ │ │ └── test_and_set_t_is_char.h
│ │ │ │ └── atomic_ops.h
│ │ │ ├── dcss/
│ │ │ │ ├── dcss_plus.h
│ │ │ │ ├── dcss_plus_impl.h
│ │ │ │ └── testing.cpp
│ │ │ ├── descriptors/
│ │ │ │ ├── descriptors.h
│ │ │ │ ├── descriptors_impl.h
│ │ │ │ └── descriptors_impl2.h
│ │ │ ├── errors.h
│ │ │ ├── plaf.h
│ │ │ ├── recordmgr/
│ │ │ │ ├── allocator_bump.h
│ │ │ │ ├── allocator_interface.h
│ │ │ │ ├── allocator_new.h
│ │ │ │ ├── allocator_new_segregated.h
│ │ │ │ ├── allocator_once.h
│ │ │ │ ├── arraylist.h
│ │ │ │ ├── blockbag.h
│ │ │ │ ├── blockpool.h
│ │ │ │ ├── debug_info.h
│ │ │ │ ├── debugcounter.h
│ │ │ │ ├── debugprinting.h
│ │ │ │ ├── globals.h
│ │ │ │ ├── hashtable.h
│ │ │ │ ├── lockfreeblockbag.h
│ │ │ │ ├── pool_interface.h
│ │ │ │ ├── pool_none.h
│ │ │ │ ├── pool_perthread_and_shared.h
│ │ │ │ ├── reclaimer_debra.h
│ │ │ │ ├── reclaimer_debraplus.h
│ │ │ │ ├── reclaimer_hazardptr.h
│ │ │ │ ├── reclaimer_interface.h
│ │ │ │ ├── reclaimer_none.h
│ │ │ │ ├── reclaimer_rcu.h
│ │ │ │ ├── record_manager.h
│ │ │ │ ├── record_manager_single_type.h
│ │ │ │ └── recovery_manager.h
│ │ │ ├── rq/
│ │ │ │ ├── rq_dcssp.h
│ │ │ │ ├── rq_debugging.h
│ │ │ │ ├── rq_htm_rwlock.h
│ │ │ │ ├── rq_provider.h
│ │ │ │ ├── rq_rwlock.h
│ │ │ │ ├── rq_snapcollector.h
│ │ │ │ ├── rq_unsafe.h
│ │ │ │ └── snapcollector/
│ │ │ │ ├── reportitem.h
│ │ │ │ ├── snapcollector.h
│ │ │ │ └── snapcollector_test.cpp
│ │ │ └── rwlock.h
│ │ ├── ds/
│ │ │ └── brown_ext_abtree_lf/
│ │ │ ├── brown_ext_abtree_lf.h
│ │ │ ├── brown_ext_abtree_lf_adapter.h
│ │ │ └── brown_ext_abtree_lf_impl.h
│ │ └── minimal_example.cpp
│ └── trevor_brown_natarajan/
│ ├── TrevorBrownNatarajanTree.hpp
│ └── ds/
│ └── natarajan_ext_bst_lf/
│ ├── natarajan_ext_bst_lf_adapter.h
│ ├── natarajan_ext_bst_lf_stage1.h
│ └── natarajan_ext_bst_lf_stage2_impl.h
├── graphs/
│ ├── BenchmarkLatencyCounter.hpp
│ ├── BenchmarkLatencyQueues.hpp
│ ├── BenchmarkMaps.hpp
│ ├── BenchmarkQueues.hpp
│ ├── BenchmarkSPS.hpp
│ ├── BenchmarkSets.hpp
│ ├── Makefile
│ ├── PBenchmarkQueues.hpp
│ ├── PBenchmarkSPS.hpp
│ ├── PBenchmarkSets.hpp
│ ├── README.md
│ ├── bin/
│ │ └── .gitignore
│ ├── data/
│ │ └── README.md
│ ├── latency-counter.cpp
│ ├── lib/
│ │ └── .gitignore
│ ├── plots/
│ │ ├── caption.gp
│ │ ├── latency-counter.gp
│ │ ├── pcaption.gp
│ │ ├── plot-all.sh
│ │ ├── plot.sh
│ │ ├── pq-enq-deq.gp
│ │ ├── pq-ll-enq-deq.gp
│ │ ├── pset-hash-1k.gp
│ │ ├── pset-ll-1k.gp
│ │ ├── pset-tree-1k.gp
│ │ ├── pset-tree-1m.gp
│ │ ├── psps-integer.gp
│ │ ├── q-array-enq-deq.gp
│ │ ├── q-enq-deq.gp
│ │ ├── q-ll-enq-deq.gp
│ │ ├── set-hash-1k.gp
│ │ ├── set-ll-10k.gp
│ │ ├── set-ll-1k.gp
│ │ ├── set-tree-10k.gp
│ │ ├── set-tree-1k.gp
│ │ ├── sps-integer.gp
│ │ ├── sps-object.gp
│ │ ├── stress-multi-process-q.gp
│ │ └── styles.inc
│ ├── pq-ll-enq-deq.cpp
│ ├── pread-while-writing.cpp
│ ├── pset-hash-1k.cpp
│ ├── pset-ll-10k.cpp
│ ├── pset-ll-1k.cpp
│ ├── pset-tree-1k.cpp
│ ├── pset-tree-1m.cpp
│ ├── psps-integer.cpp
│ ├── q-array-enq-deq.cpp
│ ├── q-ll-enq-deq.cpp
│ ├── run-all-aws.sh
│ ├── set-hash-1k.cpp
│ ├── set-ll-10k.cpp
│ ├── set-ll-1k.cpp
│ ├── set-tree-10k.cpp
│ ├── set-tree-1k.cpp
│ ├── set-tree-1m.cpp
│ ├── sps-integer.cpp
│ └── sps-object.cpp
├── pdatastructures/
│ ├── README.md
│ ├── TMHashMap.hpp
│ ├── TMHashMapByRef.hpp
│ ├── TMLinkedListQueue.hpp
│ ├── TMLinkedListSet.hpp
│ ├── TMLinkedListSetByRef.hpp
│ ├── TMRedBlackTree.hpp
│ ├── TMRedBlackTreeByRef.hpp
│ └── pqueues/
│ ├── HazardPointers.hpp
│ ├── MichaelScottQueue.hpp
│ ├── PFriedmanQueue.hpp
│ ├── PMDKLinkedListQueue.hpp
│ ├── PMichaelScottQueue.hpp
│ ├── POFLFLinkedListQueue.hpp
│ ├── POFLFMPLinkedListQueue.hpp
│ ├── POFWFLinkedListQueue.hpp
│ ├── RomLRLinkedListQueue.hpp
│ └── RomLogLinkedListQueue.hpp
├── ptms/
│ ├── OneFilePTMLF.hpp
│ ├── OneFilePTMLFMultiProcess.hpp
│ ├── OneFilePTMWF.hpp
│ ├── PMDKTM.hpp
│ ├── README.md
│ ├── atlas/
│ │ ├── README.md
│ │ └── atlas.patch
│ ├── romuluslog/
│ │ ├── RomulusLog.cpp
│ │ ├── RomulusLog.hpp
│ │ └── malloc.cpp
│ ├── romuluslr/
│ │ ├── RomulusLR.cpp
│ │ ├── RomulusLR.hpp
│ │ └── malloc.cpp
│ └── rwlocks/
│ ├── CRWWP.hpp
│ └── CRWWP_SpinLock.hpp
└── stms/
├── CRWWPSTM.hpp
├── ESTM.hpp
├── OneFileLF.hpp
├── OneFileWF.hpp
├── TinySTM.hpp
├── estm-0.3.0/
│ ├── .gitignore
│ ├── AUTHORS
│ ├── COPYING
│ ├── Makefile
│ ├── Makefile.in
│ ├── README
│ ├── VERSIONS
│ ├── include/
│ │ ├── mod_local.h
│ │ ├── mod_mem.h
│ │ ├── mod_print.h
│ │ ├── mod_stats.h
│ │ ├── stm.h
│ │ └── wrappers.h
│ └── src/
│ ├── atomic.h
│ ├── atomic_ops/
│ │ ├── AUTHORS
│ │ ├── COPYING
│ │ ├── README
│ │ ├── aligned_atomic_load_store.h
│ │ ├── all_acquire_release_volatile.h
│ │ ├── ao_t_is_int.h
│ │ ├── atomic_ops.h
│ │ ├── generalize-small.h
│ │ ├── generalize.h
│ │ ├── ia64.h
│ │ ├── ordered_except_wr.h
│ │ ├── powerpc.h
│ │ ├── read_ordered.h
│ │ ├── sparc.h
│ │ ├── standard_ao_double_t.h
│ │ ├── test_and_set_t_is_ao_t.h
│ │ ├── test_and_set_t_is_char.h
│ │ ├── x86.h
│ │ └── x86_64.h
│ ├── gc.c
│ ├── gc.h
│ ├── mod_local.c
│ ├── mod_mem.c
│ ├── mod_print.c
│ ├── mod_stats.c
│ ├── stm.c
│ └── wrappers.c
└── tinystm/
├── ChangeLog
├── Doxyfile
├── GNU-LICENSE.txt
├── MIT-LICENSE.txt
├── Makefile
├── Makefile.clang
├── Makefile.common
├── Makefile.gcc
├── Makefile.icc
├── Makefile.suncc
├── README.md
├── abi/
│ ├── Makefile
│ ├── Makefile.common
│ ├── abi.c
│ ├── arch_x86.S
│ ├── dtmc/
│ │ ├── Makefile
│ │ ├── arch.S
│ │ ├── libitm.h
│ │ ├── libtanger-stm.public-symbols
│ │ ├── libtanger-stm.support
│ │ ├── tanger-stm-internal.h
│ │ ├── tanger.c
│ │ ├── tanger.h
│ │ └── tm_macros.h
│ ├── gcc/
│ │ ├── Makefile
│ │ ├── alloc_cpp.c
│ │ ├── arch.S
│ │ ├── clone.c
│ │ ├── eh.c
│ │ ├── libitm.h
│ │ └── tm_macros.h
│ ├── intel/
│ │ ├── Makefile
│ │ ├── alloc.c
│ │ ├── arch.S
│ │ ├── libitm.h
│ │ └── tm_macros.h
│ ├── libitm.h.tpl.cpp
│ ├── libitm.h.tpl.footer
│ ├── libitm.h.tpl.header
│ ├── libitm.h.tpl.unifdef
│ ├── oracle/
│ │ ├── Makefile
│ │ ├── arch.S
│ │ └── otm.c
│ ├── pthread_wrapper.h
│ ├── test/
│ │ └── Makefile
│ └── tm_macros.h
├── include/
│ ├── mod_ab.h
│ ├── mod_cb.h
│ ├── mod_log.h
│ ├── mod_mem.h
│ ├── mod_order.h
│ ├── mod_print.h
│ ├── mod_stats.h
│ ├── stm.h
│ └── wrappers.h
├── lib/
│ └── .gitignore
├── src/
│ ├── .gitignore
│ ├── atomic.h
│ ├── atomic_ops/
│ │ ├── AUTHORS
│ │ ├── COPYING
│ │ ├── README
│ │ ├── aligned_atomic_load_store.h
│ │ ├── all_acquire_release_volatile.h
│ │ ├── ao_t_is_int.h
│ │ ├── atomic_ops.h
│ │ ├── generalize-small.h
│ │ ├── generalize.h
│ │ ├── ia64.h
│ │ ├── ordered_except_wr.h
│ │ ├── powerpc.h
│ │ ├── read_ordered.h
│ │ ├── sparc.h
│ │ ├── standard_ao_double_t.h
│ │ ├── test_and_set_t_is_ao_t.h
│ │ ├── test_and_set_t_is_char.h
│ │ ├── x86.h
│ │ └── x86_64.h
│ ├── gc.c
│ ├── gc.h
│ ├── mod_ab.c
│ ├── mod_cb_mem.c
│ ├── mod_log.c
│ ├── mod_order.c
│ ├── mod_print.c
│ ├── mod_stats.c
│ ├── stm.c
│ ├── stm_internal.h
│ ├── stm_wbctl.h
│ ├── stm_wbetl.h
│ ├── stm_wt.h
│ ├── tls.h
│ ├── utils.h
│ └── wrappers.c
└── test/
├── Makefile
├── intset/
│ ├── .gitignore
│ ├── Makefile
│ ├── README.rbtree
│ ├── intset.c
│ ├── rbtree.c
│ ├── rbtree.h
│ ├── tm.h
│ └── types.h
└── regression/
├── .gitignore
├── Makefile
├── irrevocability.c
├── perf.c
└── types.c
================================================
FILE CONTENTS
================================================
================================================
FILE: LICENSE.txt
================================================
Copyright (c) 2017-2018
Andreia Correia <andreia.veiga@unine.ch>
Pedro Ramalhete <pramalhe@gmail.com>
Pascal Felber <pascal.felber@unine.ch>
Nachshon Cohen <nachshonc@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# OneFile PTM / STM
OneFile is a Software Transactional Memory (STM) meant to make it easy to implement lock-free and wait-free data structures.
It is based on the paper "[OneFile: A Wait-free Persistent Transactional Memory](https://github.com/pramalhe/OneFile/blob/master/OneFile-2019.pdf)" by Ramalhete, Correia, Felber and Cohen
https://github.com/pramalhe/OneFile/blob/master/OneFile-2019.pdf
It provides multi-word atomic updates on *tmtype<T>* objects, where T must be word-size, typically a pointer or integer.
During a transaction, each store on an *tmtpye<T>* is transformed into a double-word-compare-and-swap DCAS() and one more regular CAS() is done to complete the transaction. It does this with a store-log (write-set) which other writers can help apply.
This is a "redo-log" based technique, which means that both store and loads need to be interposed. Stores will be interposed to save them in the log and loads will be interposed to lookup on the log the most recent value.
If there is a transaction currently ongoing, the readers will have to check on each *tmtype::pload()* if the variable we're tying to read is part of the current transaction. If a value is read whose 'seq' is higher than the transaction we initially read, the whole read-only operation will be restarted, by throwing an exception in the *tmtype::pload()* interposing method and catching this exception by the TM. All of this logic is handled internally by OF without any explicit user interaction.
Because of operator overloading, the assignment and reading of *tmtype<T>* types is done transparently to the user, with a pure library implementation, without any need for compiler instrumentation. This means that the user can write the code as if it was a sequential implementation of the data structure, apart from the change of types (type annotation). In this sense, OneFile is a "quasi-universal construction" with lock-free progress.
Our design goal with OneFile was to provide a non-blocking STM so that non-experts could implement their own lock-free and wait-free data structures.
OneFile is not designed to transform regular everyday code into lock-free applications. Such use-cases require a lot more of engineering work and likely a completely different approach from what we took with OneFile (CX is a much better option for that purpose).
We've made two implementations in the form of Persistent Transactional Memory (PTM) which are STMs meant for Persistent Memory, like Intel's Optane DC Persistent Memory.
We've implemented four diferent variants of this design:
- OneFile-LF: The simplest of the four, has lock-free progress and lock-free memory reclamation using Hazard Eras;
- OneFile-WF: Uses aggregation (like flat-combining) and a new wait-free consensus to provide wait-free bounded progress. Has wait-free bounded memory reclamation;
- POneFile-LF: A PTM with durable transactions (ACID) and lock-free progress. Memory reclamation is lock-free using an optimistic technique. Allocation and de-allocation of user objects is lock-free;
- POnefile-WF: A PTM with durable transactions (ACID) and wait-free progress. Memory reclamation for user objects is wait-free using an optimistic technique, while memory reclamation of the transactional objects is done using Hazard Eras, also wait-free. Allocation and de-allocation of user-objects is wait-free;
See the respective .hpp files for implementation details.
Each implementation is a single header file. Yes, it's that small :)
## Quickstart ##
If you just want to use OneFile in your own application or benchmarks then follow these steps:
- Choose one of the four OneFile implementations, depending on whether you want and STM, a PTM, lock-free or wait-free progress:
[stms/OneFileLF.hpp](https://github.com/pramalhe/OneFile/blob/master/stms/OneFileLF.hpp) STM with lock-free transactions
[stms/OneFileWF.hpp](https://github.com/pramalhe/OneFile/blob/master/stms/OneFileWF.hpp) STM with wait-free transactions
[ptms/POneFileLF.hpp](https://github.com/pramalhe/OneFile/blob/master/ptms/OneFilePTMLF.hpp) PTM with lock-free transactions
[ptms/POneFileWF.hpp](https://github.com/pramalhe/OneFile/blob/master/ptms/OneFilePTMWF.hpp) PTM with wait-free transactions
- Copy the header to your development folder
- Include the header from a single .cpp. If you include from multiple compilation units (.cpp files) then move the last block in the .hpp to one of the .cpp files.
- If you want a data structure that is already made then take a look at what's on these folders:
datastructures/ Data structures for volatile memory (needs one of the STMs)
pdatastructures/ Data structures for persistent memory (needs one of the PTMs)
### Design ###
In OneFile STM a transaction goes through three phases.
The first phase is to convert the operation (lambda) into a store-log (write-set). There is no need to save the loads (read-set) because unlike other approaches, a transaction does not need to re-check for changes at commit time: it does a check in-flight on each load of whether or not the value has changed since the beginning of the transaction, by looking at a sequence number associated with every read value, a technique similar to TL2 or TinySTM but without the need for keeping a read-set because all write transactions are executed one at a time, effectively serialized.
The second phase is to commit the transaction by advancing the current transaction (curTx).
The third phase is to apply the store-log using DCAS.
The first phase is implicitly serializable. Even if each thread publishes its operation, there is no way to parallelize this work among threads. The best that could be done would be that each thread to transform its own operation into its own store-log which it then appends to a global store-log. Unfortunately this is possible only for disjoint-access parallel transactions, and these are not easy to detect, therefore, our implementation of OneFile does not do this.
Instead, we attempt to parallelize the second stage, where the store-log is applied. This task is easier to split among multiple threads, thus parallelizing it.
Adding Flat-Combining or other similar aggregation techniques to the first stage, means that each thread will produce a store-log containing the operations of all other threads. This can be a bottleneck if the operations involves heavy computations and small store-logs. For data structures, this is not the case, and OneFile is designed to implement and work with data structures or other scenarios where the transactions are short in time, therefore, we found it acceptable to go with such an approach.
The parallelization of the third phase can be done with at least two different approaches: blocking and non-blocking.
In the blocking approach, the store-log can be divided into chunks (for example, one chunk per thread), each chunk having a lock, and the thread that takes the lock is responsible for applying that chunk.
In the non-blocking approach (OF-LF and OF-WF), each thread tries to apply an entry of the store-log at a time. To avoid ABA issues, a double-word compare-and-swap (DCAS) must be used.
In summary, OneFile does *not* do disjoint-access parallel transactions. If you absolutely need that functionality, then go and take a look at TinySTM.
## Requirements ##
- OneFile needs a double-word CAS, which limits it to x86. The algorithm can be modified to use LL/SC or even single-word CAS at the cost of losing its generic capability because bits would have to be stolen from a 64 bit wordl
- The user must "instrument" the code where the atomic updates take place by wrapping the types with *tmtype<T>*. Even then, the operator overloading will not cover all the cases and there will be situations where the user has to annotate the code with .pload() or .pstore() respectively;
- The *T* type must be the size of a word, i.e. 64 bits. Anything bigger and it needs to be splitted into multiple *tmtype<T>* objects;
- If memory reclamation is needed, then the objects need to derive from the *tmbase* base class, need to be allocated with *tmNew()* or *tmMalloc()* and deallocated with *tmDelete()* or *tmFree()*;
## Memory Reclamation ##
We're using a customized implementation of Hazard Eras, lock-free/wait-free memory reclamation:
[https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/hazarderas-2017.pdf](https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/hazarderas-2017.pdf)
[https://dl.acm.org/citation.cfm?id=3087588](https://dl.acm.org/citation.cfm?id=3087588)
See the HazardErasOF class in each implementation for more details.
As far as we know, there is only one wait-free data structure that has integrated wait-free memory reclamation:
[https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/crturnqueue-2016.pdf]([https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/crturnqueue-2016.pdf)
OneFile and CX are the first time that someone has made a generic mechanism for wait-free memory reclamation.
## How to use this ##
1. Annotate all the objects that are shared among threads, namely, everything that is *std::atomic<T>* should be changed to *tmtype<T>*;
2. Use only *pstore()* and *pload()* (or just use '='). Do *not* call compare_exchange_strong(), exchange() or fetch_add();
3. Replace calls to "obj = new T(args)" with "obj = tmNew<T>(args)";
4. Replace calls to "delete obj" with "tmDelete<T>(obj)";
5. The T types must derive from the base class *tmbase*;
6. Place your methods in a lambda, capturing whatever you need, and pass the lambda to *updateTx()*;
That's it, you've now got your own lock-free data structure!
For an example of a simple linked-list set, take a look datastructures/linkedlists/OFLFLinkedListSet.hpp
## Disadvantages ##
- All mutative operations are serialized;
- Types must be broken down to 64 bit sizes;
- Requires Double-word-compare-and-swap (DCAS);
## Advantages ##
- Lock-free programming was never so easy, all the user code has to do is loads and stores on *tmtypes<T>* types and those get transformed into a DCAS() based transaction that provides correct linearizable lock-free progress, without ABA issues;
- Memory reclamation is also handled by OF using Hazard Eras, a lock-free/wait-free memory reclamation technique;
- Compared to hand-written lock-free data structures, on the uncontended case, we are replacing each CAS with a DCAS and adding one extra (regular) CAS on the currTrans, which is a small price to pay for the atomicity;
- This technique provides full linearizability for generic code, even mutative iterators, something which is nearly impossible to do with hand-written lock-free data structures;
- Multiple helping threads can help apply starting on different places. A good heuristic is to start from the (tid % numStores);
- OneFile-WF is the first STM with wait-free bounded progress and it's the first to have wait-free bounded progress with wait-free bounded memory reclamation.
- Read-only transactions are lightweight and they can run concurrently with write transactions as long as they're disjoint;
The biggest advantage of all is that it's way easier to use OneFile than it is to implement a hand-made lock-free or wait-free data structure.
## Examples ##
There are some working examples in the "datastructures/" folder:
OFLFBoundedQueue.hpp: An array based queue (memory-bounded)
OFLFLinkedListQueue.hpp: A linked list based queue (memory unbounded)
OFLFLinkedListSet.hpp: A linked list based set
OFLFRedBlackBST.hpp: A Red-Black (balanced) tree map
## Benchmarks ##
To build the benchmarks you need to build ESTM and TinySTM, and then you need to pull PMDK (PMEM/NVML) and build it:
cd ~/onefile/stms/
cd estm-0.3.0
make clean ; make
cd ..
cd tinystm
make clean ; make
cd ..
cd ~
git clone https://github.com/pmem/pmdk.git
cd pmdk
make -j12
sudo make install
export PMEM_IS_PMEM_FORCE=1
cd ~/onefile/graphs
make -j12
## Tests ##
The four implementations of OneFile were executed during thousands of cpu hours and heavily stress tested with invariant checking and using tools like address sanitizer and valgrind. This is a lot more than what other STMs on github provide, but it doesn't mean there are no bugs in it ;)
If you see a crash or invariant failure, run the same code under a global rw-lock to make sure the bug is not in your code. If you really believe it's in OneFile, then please open a bug on github and add as much information as you can, namely, stack trace and files needed to reproduce.
We'll do our best to address it.
================================================
FILE: common/HazardEras.hpp
================================================
/******************************************************************************
* Copyright (c) 2016-2017, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _HAZARD_ERAS_H_
#define _HAZARD_ERAS_H_
#include <atomic>
#include <iostream>
#include <vector>
#include <algorithm>
/*
* <h1> Hazard Eras </h1>
* This a light-weight implementation of hazard eras, where each thread has a
* thread-local list of retired objects.
*
* This is based on the paper "Hazard Eras - Non-Blocking Memory Reclamation"
* by Pedro Ramalhete and Andreia Correia:
* github...
*
* The type T is for the objects/nodes and it's expected to have the following members:
* newEra, delEra, delNext.
*
* R is zero.
*
* <p>
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class HazardEras {
private:
static const uint64_t NONE = 0;
static const int HE_MAX_THREADS = 128;
static const int MAX_HES = 5; // This is named 'K' in the HP paper
static const int CLPAD = 128/sizeof(std::atomic<T*>);
static const int HE_THRESHOLD_R = 0; // This is named 'R' in the HP paper
const int maxHEs;
const int maxThreads;
alignas(128) std::atomic<uint64_t> eraClock {1};
alignas(128) std::atomic<uint64_t>* he[HE_MAX_THREADS];
alignas(128) std::vector<T*> retiredList[HE_MAX_THREADS*CLPAD]; // It's not nice that we have a lot of empty vectors
public:
HazardEras(int maxHEs=MAX_HES, int maxThreads=HE_MAX_THREADS) : maxHEs{maxHEs}, maxThreads{maxThreads} {
for (int it = 0; it < HE_MAX_THREADS; it++) {
he[it] = new std::atomic<uint64_t>[CLPAD*2]; // We allocate four cache lines to allow for many hps and without false sharing
retiredList[it*CLPAD].reserve(maxThreads*maxHEs);
for (int ihe = 0; ihe < MAX_HES; ihe++) {
he[it][ihe].store(NONE, std::memory_order_relaxed);
}
}
static_assert(std::is_same<decltype(T::newEra), uint64_t>::value, "T::newEra must be uint64_t");
static_assert(std::is_same<decltype(T::delEra), uint64_t>::value, "T::delEra must be uint64_t");
}
~HazardEras() {
for (int it = 0; it < HE_MAX_THREADS; it++) {
delete[] he[it];
// Clear the current retired nodes
for (unsigned iret = 0; iret < retiredList[it*CLPAD].size(); iret++) {
delete retiredList[it*CLPAD][iret];
}
}
}
inline uint64_t getEra() {
return eraClock.load();
}
/**
* Progress Condition: wait-free bounded (by maxHEs)
*/
inline void clear(const int tid) {
for (int ihe = 0; ihe < maxHEs; ihe++) {
he[tid][ihe].store(NONE, std::memory_order_release);
}
}
/**
* Progress Condition: lock-free
*/
inline T* get_protected(int index, const std::atomic<T*>& atom, const int tid) {
auto prevEra = he[tid][index].load(std::memory_order_relaxed);
while (true) {
T* ptr = atom.load();
auto era = eraClock.load(std::memory_order_acquire);
if (era == prevEra) return ptr;
he[tid][index].store(era);
prevEra = era;
}
}
inline void protectEraRelease(int index, int other, const int tid) {
auto era = he[tid][other].load(std::memory_order_relaxed);
if (he[tid][index].load(std::memory_order_relaxed) == era) return;
he[tid][index].store(era, std::memory_order_release);
}
/*
* Does a single iteration. Must be integrated into the algorithm that's using HE.
* In other words, we must re-check if era has changed
*
* Progress Condition: wait-free population oblivious
*/
inline T* protectPtr(int index, const std::atomic<T*>& atom, uint64_t& prevEra, const int tid) {
T* ptr = atom.load(std::memory_order_acquire);
auto era = eraClock.load();
if (prevEra != era) {
prevEra = era;
he[tid][index].store(era, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
return ptr;
}
/**
* Retire an object (node)
* Progress Condition: wait-free bounded
*/
void retire(T* ptr, const int mytid) {
auto currEra = eraClock.load();
ptr->delEra = currEra;
auto& rlist = retiredList[mytid*CLPAD];
rlist.push_back(ptr);
if (eraClock == currEra) eraClock.fetch_add(1);
for (unsigned iret = 0; iret < rlist.size();) {
auto obj = rlist[iret];
if (canDelete(obj, mytid)) {
rlist.erase(rlist.begin() + iret);
delete obj;
continue;
}
iret++;
}
}
private:
bool canDelete(T* obj, const int mytid) {
for (int tid = 0; tid < maxThreads; tid++) {
for (int ihe = 0; ihe < maxHEs; ihe++) {
const auto era = he[tid][ihe].load(std::memory_order_acquire);
if (era == NONE || era < obj->newEra || era > obj->delEra) continue;
return false;
}
}
return true;
}
};
#endif /* _HAZARD_ERAS_H_ */
================================================
FILE: common/HazardPointers.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _HAZARD_POINTERS_H_
#define _HAZARD_POINTERS_H_
#include <atomic>
#include <iostream>
/**
* This is a customized version of Hazard Pointers to be used with CXMutation
*/
// TODO: use std::vector instead of arrays for the retired objects (keep the padding)
template<typename T>
class HazardPointers {
private:
static const int MAX_THREADS = 128;
static const int MAX_HPS = 5;
static const int MAX_RETIRED = MAX_THREADS*MAX_HPS;
static const int HP_THRESHOLD_R = 0; // This is named 'R' in the HP paper
static const int CLPAD = 128/sizeof(std::atomic<T*>);
const int maxHPs;
const int maxThreads;
alignas(128) std::atomic<T*>* hp[MAX_THREADS*CLPAD];
alignas(128) T** retiredObjects[MAX_THREADS*CLPAD]; // List of retired nodes that need to be 'deleted' for the current thread
alignas(128) long numRetiredObjects[MAX_THREADS*CLPAD]; // Number of nodes in the retired list
// Used specifically for CXMutation
alignas(128) std::atomic<T*> heads[2*MAX_THREADS*CLPAD];
public:
HazardPointers(int maxHPs=MAX_HPS, int maxThreads=MAX_THREADS) : maxHPs{maxHPs}, maxThreads{maxThreads} {
for (int ih = 0; ih < 2*MAX_THREADS; ih++) {
heads[ih*CLPAD].store(nullptr, std::memory_order_relaxed);
}
for (int ithread = 0; ithread < MAX_THREADS; ithread++) {
numRetiredObjects[ithread*CLPAD] = 0;
hp[ithread*CLPAD] = new std::atomic<T*>[MAX_HPS];
for (int ihp = 0; ihp < MAX_HPS; ihp++) {
hp[ithread*CLPAD][ihp].store(nullptr, std::memory_order_relaxed);
}
retiredObjects[ithread*CLPAD] = new T*[MAX_RETIRED];
for (int iret = 0; iret < MAX_RETIRED; iret++) {
retiredObjects[ithread*CLPAD][iret] = nullptr;
}
}
}
~HazardPointers() {
for (int ithread = 0; ithread < MAX_THREADS; ithread++) {
// Clear the current retired nodes
for (int iret = 0; iret < numRetiredObjects[ithread*CLPAD]; iret++) {
delete (T*)retiredObjects[ithread*CLPAD][iret];
}
delete[] hp[ithread*CLPAD];
delete[] retiredObjects[ithread*CLPAD];
}
}
/**
* Progress Condition: wait-free bounded (by maxHPs)
*
* It's ok to use relaxed loads here because:
* - For progress: we know that the store will eventually become visible,
* or another publish() will take its place;
* - For correctness: it can be re-ordered below, but at most it will protect
* an object for longer than required, i.e. until the next publish overwrites it.
* Or it gets re-ordered above, but only up to a seq-cst store on the same
* variable in publish(), which _must_ be it, even if the store in the publish
* is a release store (which is the case for publishRelease()).
*/
void clear(const int tid) {
for (int ihp = 0; ihp < maxHPs; ihp++) {
hp[tid*CLPAD][ihp].store(nullptr, std::memory_order_relaxed);
}
}
/**
* Progress Condition: wait-free population oblivious
*/
void clearOne(int ihp, const int tid) {
hp[tid*CLPAD][ihp].store(nullptr,std::memory_order_relaxed);
}
/**
* Progress Condition: lock-free
*/
T* protect(int index, const std::atomic<T*>& atom, const int tid) {
T* n = nullptr;
T* ret;
while ((ret = atom.load()) != n) {
hp[tid*CLPAD][index].store(ret);
n = ret;
}
return ret;
}
inline T* get_protected(int index, const std::atomic<T*>& atom, const int tid) {
return protect(index, atom, tid);
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free population oblivious
*/
T* protectPtr(int index, T* ptr, const int tid) {
hp[tid*CLPAD][index].store(ptr);
return ptr;
}
/**
* This assumes that the ptr lhead is already protected by a "regular" hazard pointers
*/
void protectHead(int combinedIndex, T* lhead) {
heads[combinedIndex*CLPAD].store(lhead, std::memory_order_release);
}
std::atomic<T*>* getHeads() {
return heads;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free population oblivious
*/
T* protectRelease(int index, T* ptr, const int tid) {
hp[tid*CLPAD][index].store(ptr, std::memory_order_release);
return ptr;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free bounded (by the number of threads squared)
*/
void retire(T* ptr, const int tid) {
if (numRetiredObjects[tid*CLPAD] >= HP_THRESHOLD_R) scanAndDelete(tid);
retiredObjects[tid*CLPAD][numRetiredObjects[tid*CLPAD]++] = ptr;
}
void copyPtr(int index, int other, const int tid) {
auto ptr = hp[tid*CLPAD][other].load(std::memory_order_relaxed);
hp[tid*CLPAD][index].store(ptr, std::memory_order_release);
}
private:
void scanAndDelete(const int tid) {
for (int iret = 0; iret < numRetiredObjects[tid*CLPAD]; ) {
bool ptrInUse = false;
auto ptr = (T*)retiredObjects[tid*CLPAD][iret];
for (int it = 0; it < maxThreads; it++) {
for (int ihp = maxHPs-1; ihp >= 0; ihp--) {
if (ptr == hp[it*CLPAD][ihp].load()) ptrInUse = true;
}
}
if (ptrInUse) { iret++; continue; }
// Scan the array of heads before deleting the pointer
for (int icomb = 0; icomb < 2*MAX_THREADS; icomb++) {
if (ptr == heads[icomb*CLPAD].load()) ptrInUse = true;
}
if (ptrInUse) { iret++; continue; }
for (int i = iret; i < numRetiredObjects[tid*CLPAD]-1; i++) retiredObjects[tid*CLPAD][i] = retiredObjects[tid*CLPAD][i+1];
numRetiredObjects[tid*CLPAD]--;
delete ptr;
}
}
};
#endif /* _HAZARD_POINTERS_H_ */
================================================
FILE: common/HazardPointersSimQueue.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _HAZARD_POINTERS_SIM_QUEUE_H_
#define _HAZARD_POINTERS_SIM_QUEUE_H_
#include <atomic>
#include <iostream>
#include <functional>
#include <vector>
/*
* The main difference from this implementation to regular Hazard Pointers is
* that the constructor takes a function pointer to function 'find' which
* acts as a callback, returning true if the pointer is still stored somewhere
* in the data structure. This is used by SimQueue to indicate if there is a
* pointer to the object we're trying to de-allocate in the array of enqReused.
*/
template<typename T>
class HazardPointersSimQueue {
private:
static const int HP_MAX_THREADS = 128;
static const int HP_MAX_HPS = 11; // This is named 'K' in the HP paper
static const int CLPAD = 128/sizeof(std::atomic<T*>);
static const int HP_THRESHOLD_R = 0; // This is named 'R' in the HP paper
static const int MAX_RETIRED = HP_MAX_THREADS*HP_MAX_HPS; // Maximum number of retired objects per thread
const int maxHPs;
const int maxThreads;
std::atomic<T*> hp[HP_MAX_THREADS*CLPAD][HP_MAX_HPS];
// It's not nice that we have a lot of empty vectors, but we need padding to avoid false sharing
std::vector<T*> retiredList[HP_MAX_THREADS*CLPAD];
std::function<bool(T*)> findPtr;
public:
HazardPointersSimQueue(std::function<bool(T*)>& find, int maxHPs=HP_MAX_HPS, int maxThreads=HP_MAX_THREADS) : maxHPs{maxHPs}, maxThreads{maxThreads} {
findPtr = find;
for (int ithread = 0; ithread < HP_MAX_THREADS; ithread++) {
for (int ihp = 0; ihp < HP_MAX_HPS; ihp++) {
hp[ithread*CLPAD][ihp].store(nullptr, std::memory_order_relaxed);
}
}
}
~HazardPointersSimQueue() {
for (int ithread = 0; ithread < HP_MAX_THREADS; ithread++) {
// Clear the current retired nodes
for (unsigned iret = 0; iret < retiredList[ithread*CLPAD].size(); iret++) {
delete retiredList[ithread*CLPAD][iret];
}
}
}
/**
* Progress Condition: wait-free bounded (by maxHPs)
*/
void clear(const int tid) {
for (int ihp = 0; ihp < maxHPs; ihp++) {
hp[tid*CLPAD][ihp].store(nullptr, std::memory_order_release);
}
}
/**
* Progress Condition: wait-free population oblivious
*/
void clearOne(int ihp, const int tid) {
hp[tid*CLPAD][ihp].store(nullptr, std::memory_order_release);
}
/**
* Progress Condition: lock-free
*/
T* protect(int index, const std::atomic<T*>& atom, const int tid) {
T* n = nullptr;
T* ret;
while ((ret = atom.load()) != n) {
hp[tid*CLPAD][index].store(ret);
n = ret;
}
return ret;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free population oblivious
*/
T* protectPtr(int index, T* ptr, const int tid) {
hp[tid*CLPAD][index].store(ptr);
return ptr;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free population oblivious
*/
T* protectRelease(int index, T* ptr, const int tid) {
hp[tid*CLPAD][index].store(ptr, std::memory_order_release);
return ptr;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free bounded (by the number of threads squared)
*/
void retire(T* ptr, const int tid) {
retiredList[tid*CLPAD].push_back(ptr);
for (unsigned iret = 0; iret < retiredList[tid*CLPAD].size();) {
auto obj = retiredList[tid*CLPAD][iret];
if (findPtr(obj)) {
iret++;
continue;
}
bool canDelete = true;
for (int tid = 0; tid < maxThreads && canDelete; tid++) {
for (int ihp = maxHPs-1; ihp >= 0; ihp--) {
if (hp[tid*CLPAD][ihp].load() == obj) {
canDelete = false;
break;
}
}
}
if (canDelete) {
retiredList[tid*CLPAD].erase(retiredList[tid*CLPAD].begin() + iret);
delete obj;
continue;
}
iret++;
}
}
};
#endif /* _HAZARD_POINTERS_H_ */
================================================
FILE: common/README.md
================================================
Here are some files that are needed by other libraries and data structures:
HazardEras.hpp Used by some of the lock-free data structures for memory reclamation
HazardPointers.hpp Used by some of the lock-free data structures for memory reclamation
HazardPointersSimQueue.hpp Used by SimQueue for memory reclamation. Notice that the original SimQueue implementation in C does not ha memory reclamation. This implementation in C++ with this modified version of Hazard Pointers was done by Correia and Ramalhete
pfences.h Used by Romulus
RIStaticPerThread.hpp Used by Romulus
ThreadRegistry.cpp Used by Romulus
ThreadRegistry.hpp Used by Romulus
================================================
FILE: common/RIStaticPerThread.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _RISTATIC_H_
#define _RISTATIC_H_
#include <atomic>
#include <iostream>
#include <cstdint>
// TODO: change all calls that need the tid to use a function argument
// TODO: use std::vector instead of arrays for the retired objects (keep the padding)
class RIStaticPerThread {
private:
const int maxThreads;
alignas(128) std::atomic<uint64_t>* states;
static const uint64_t NOT_READING = 0;
static const uint64_t READING = 1;
static const int CLPAD = 128/sizeof(uint64_t);
public:
RIStaticPerThread(int maxThreads) : maxThreads{maxThreads} {
states = new std::atomic<uint64_t>[maxThreads*CLPAD];
for (int tid = 0; tid < maxThreads; tid++) {
states[tid*CLPAD].store(NOT_READING, std::memory_order_relaxed);
}
}
~RIStaticPerThread() {
delete[] states;
}
// Will attempt to pass all current READING states to
inline void abortRollback() noexcept {
for (int tid = 0; tid < maxThreads; tid++) {
if (states[tid*CLPAD].load() != READING) continue;
uint64_t read = READING;
states[tid*CLPAD].compare_exchange_strong(read, READING+1);
}
}
// Returns true if the arrival was successfully rollbacked.
// If there was a writer changing the state to READING+1 then it will
// return false, meaning that the arrive() is still valid and visible.
inline bool rollbackArrive(const int tid) noexcept {
return (states[tid*CLPAD].fetch_add(-1) == READING);
}
inline void arrive(const int tid) noexcept {
states[tid*CLPAD].store(READING);
}
inline void depart(const int tid) noexcept {
states[tid*CLPAD].store(NOT_READING); // Making this "memory_order_release" will cause overflows!
}
inline bool isEmpty() noexcept {
for (int tid = 0; tid < maxThreads; tid++) {
if (states[tid*CLPAD].load() != NOT_READING) return false;
}
return true;
}
};
#endif /* RISTATIC_H */
================================================
FILE: common/ThreadRegistry.cpp
================================================
/*
* Contains all global variables.
*/
#include "common/ThreadRegistry.hpp"
// Global/singleton to hold all the thread registry functionality
ThreadRegistry gThreadRegistry {};
// This is where every thread stores the tid it has been assigned when it calls getTID() for the first time.
// When the thread dies, the destructor of ThreadCheckInCheckOut will be called and de-register the thread.
thread_local ThreadCheckInCheckOut tl_tcico {};
void thread_registry_deregister_thread(const int tid) {
gThreadRegistry.deregister_thread(tid);
}
================================================
FILE: common/ThreadRegistry.hpp
================================================
#ifndef _THREAD_REGISTRY_H_
#define _THREAD_REGISTRY_H_
#include <atomic>
#include <thread>
#include <iostream>
#include <cassert>
// Increase this if 128 threads is not enough
static const int REGISTRY_MAX_THREADS = 128;
extern void thread_registry_deregister_thread(const int tid);
// An helper class to do the checkin and checkout of the thread registry
struct ThreadCheckInCheckOut {
static const int NOT_ASSIGNED = -1;
int tid { NOT_ASSIGNED };
~ThreadCheckInCheckOut() {
if (tid == NOT_ASSIGNED) return;
thread_registry_deregister_thread(tid);
}
};
extern thread_local ThreadCheckInCheckOut tl_tcico;
// Forward declaration of global/singleton instance
class ThreadRegistry;
extern ThreadRegistry gThreadRegistry;
/*
* <h1> Registry for threads </h1>
*
* This is singleton type class that allows assignement of a unique id to each thread.
* The first time a thread calls ThreadRegistry::getTID() it will allocate a free slot in 'usedTID[]'.
* This tid wil be saved in a thread-local variable of the type ThreadCheckInCheckOut which
* upon destruction of the thread will call the destructor of ThreadCheckInCheckOut and free the
* corresponding slot to be used by a later thread.
* RomulusLR relies on this to work properly.
*/
class ThreadRegistry {
private:
alignas(128) std::atomic<bool> usedTID[REGISTRY_MAX_THREADS]; // Which TIDs are in use by threads
alignas(128) std::atomic<int> maxTid {-1}; // Highest TID (+1) in use by threads
public:
ThreadRegistry() {
for (int it = 0; it < REGISTRY_MAX_THREADS; it++) {
usedTID[it].store(false, std::memory_order_relaxed);
}
}
/*
* Progress Condition: wait-free bounded (by the number of threads)
*/
int register_thread_new(void) {
for (int tid = 0; tid < REGISTRY_MAX_THREADS; tid++) {
if (usedTID[tid].load(std::memory_order_acquire)) continue;
bool unused = false;
if (!usedTID[tid].compare_exchange_strong(unused, true)) continue;
// Increase the current maximum to cover our thread id
int curMax = maxTid.load();
while (curMax <= tid) {
maxTid.compare_exchange_strong(curMax, tid+1);
curMax = maxTid.load();
}
tl_tcico.tid = tid;
return tid;
}
std::cout << "ERROR: Too many threads, registry can only hold " << REGISTRY_MAX_THREADS << " threads\n";
assert(false);
}
/*
* Progress condition: wait-free population oblivious
*/
inline void deregister_thread(const int tid) {
usedTID[tid].store(false, std::memory_order_release);
}
/*
* Progress condition: wait-free population oblivious
*/
static inline uint64_t getMaxThreads(void) {
return gThreadRegistry.maxTid.load(std::memory_order_acquire);
}
/*
* Progress condition: wait-free bounded (by the number of threads)
*/
static inline int getTID(void) {
int tid = tl_tcico.tid;
if (tid != ThreadCheckInCheckOut::NOT_ASSIGNED) return tid;
return gThreadRegistry.register_thread_new();
}
};
#endif /* _THREAD_REGISTRY_H_ */
================================================
FILE: common/pfences.h
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _PERSISTENT_FENCES_
#define _PERSISTENT_FENCES_
/*
* The naming for these macros and respective operations were taken from the excellent
* "Preserving Happens-before in Persistent Memory" by Izraelevitz, Mendes, and Scott
* https://www.cs.rochester.edu/u/jhi1/papers/2016-spaa-transform
*
* We have five different definitions of pwb/pfence/psync:
* - Emulated: We introduce a delay on stores, like Mnemosyne does
* - Nothing: only works with process restart persistency, i.e. process failures, but not system failure
* - Define pwb as clflush (Broadwell cpus)
* - Define pwb as clflushopt (most x86 cpus)
* - Define pwb as clwb (only very recent cpus have this instruction)
*/
/*
* We copied the methods from Menmosyne:
* http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.221.5462&rep=rep1&type=pdf
*/
static inline unsigned long long asm_rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
// Change this depending on the clock cycle of your cpu. For Cervino it's 2100, for my laptop it's 2712.
#define EMULATED_CPUFREQ 2100
#define NS2CYCLE(__ns) ((__ns) * EMULATED_CPUFREQ / 1000)
static inline void emulate_latency_ns(int ns) {
uint64_t stop;
uint64_t start = asm_rdtsc();
uint64_t cycles = NS2CYCLE(ns);
do {
/* RDTSC doesn't necessarily wait for previous instructions to complete
* so a serializing instruction is usually used to ensure previous
* instructions have completed. However, in our case this is a desirable
* property since we want to overlap the latency we emulate with the
* actual latency of the emulated instruction.
*/
stop = asm_rdtsc();
} while (stop - start < cycles);
}
/*
* We use the settings on the delays for emulation from the NVMOVE paper:
* http://www.cs.utexas.edu/~vijay/papers/inflow16-nvmove.pdf
*/
#ifdef PWB_IS_STT
/* Delays for emulating STT in DRAM */
#define PWB(addr) emulate_latency_ns(140)
#define PFENCE() emulate_latency_ns(200)
#define PSYNC() emulate_latency_ns(200)
#elif PWB_IS_PCM
/* Delays for emulating PCM in DRAM */
#define PWB(addr) emulate_latency_ns(340)
#define PFENCE() emulate_latency_ns(500)
#define PSYNC() emulate_latency_ns(500)
#elif PWB_IS_CLFLUSH
/*
* More info at http://elixir.free-electrons.com/linux/latest/source/arch/x86/include/asm/special_insns.h#L213
* Intel programming manual at https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf
* Use these for Broadwell CPUs (cervino server)
*/
#define PWB(addr) __asm__ volatile("clflush (%0)" :: "r" (addr) : "memory") // Broadwell only works with this.
#define PFENCE() {} // No ordering fences needed for CLFLUSH (section 7.4.6 of Intel manual)
#define PSYNC() {} // For durability it's not obvious, but CLFLUSH seems to be enough, and PMDK uses the same approach
#elif PWB_IS_CLWB
/* Use this for CPUs that support clwb, such as the SkyLake SP series (c5 compute intensive instances in AWS are an example of it) */
#define PWB(addr) __asm__ volatile(".byte 0x66; xsaveopt %0" : "+m" (*(volatile char *)(addr))) // clwb() only for Ice Lake onwards
#define PFENCE() __asm__ volatile("sfence" : : : "memory")
#define PSYNC() __asm__ volatile("sfence" : : : "memory")
#elif PWB_IS_NOP
/* pwbs are not needed for shared memory persistency (i.e. persistency across process failure) */
#define PWB(addr) {}
#define PFENCE() __asm__ volatile("sfence" : : : "memory")
#define PSYNC() __asm__ volatile("sfence" : : : "memory")
#elif PWB_IS_CLFLUSHOPT
/* Use this for CPUs that support clflushopt, which is most recent x86 */
#define PWB(addr) __asm__ volatile(".byte 0x66; clflush %0" : "+m" (*(volatile char *)(addr))) // clflushopt (Kaby Lake)
#define PFENCE() __asm__ volatile("sfence" : : : "memory")
#define PSYNC() __asm__ volatile("sfence" : : : "memory")
#else
#error "You must define what PWB is. Choose PWB_IS_CLFLUSHOPT if you don't know what your CPU is capable of"
#endif
// Flush each cache line in a range
// TODO: fix cache alignment
inline static void flushFromTo(void* from, void* to) noexcept {
const int cache_line_size = 64;
uint8_t* ptr = (uint8_t*)from;
for (; ptr < (uint8_t*)to; ptr += cache_line_size) PWB(ptr);
}
// TODO: Implement fences for ARM
#endif
================================================
FILE: datastructures/generic/TMHashMap.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2018, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _TM_NON_RESIZABLE_HASH_MAP_H_
#define _TM_NON_RESIZABLE_HASH_MAP_H_
#include <atomic>
#include <stdexcept>
#include <mutex>
#include "../../stms/tm.h" // This header defines the macros for the STM being compiled
/**
* <h1> A Non-Resizable Hash Map for usage with STMs </h1>
*
* Each node contains 4 entries (key/value) so as to provide better cache locality
*
*
* TODO
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename K, typename V>
class TMHashMap : public TM_BASE_TYPE {
private:
// One KeyVal is 16+16 bytes, therefore, 4 KeyVals are 2 cache lines in x86 (128 bytes)
static const int KV_NUM = 4;
static const unsigned int MAX_THREADS = 128;
const unsigned int maxThreads;
const unsigned int capacity;
struct KeyVal {
//uint64_t h; // Full hash of the key, for faster comparison. TODO: add code to handle h
TM_TYPE<K*> key {nullptr};
TM_TYPE<V*> val {nullptr};
KeyVal() {}
KeyVal(K* key, V* value) : key{key}, val{value} { }
};
struct Node : TM_BASE_TYPE {
KeyVal kv[KV_NUM];
TM_TYPE<Node*> next {nullptr};
Node() {}
Node(K* key, V* value) {
kv[0].key = key;
kv[0].val = value;
}
bool isEmpty() {
for (int i = 0; i < KV_NUM; i++) {
if (kv[i].key != nullptr) return false;
}
return true;
}
};
alignas(128) Node* buckets; // An array of Nodes
int myhash(K* key) { return 0; } // Used only for tests
public:
TMHashMap(unsigned int maxThreads=MAX_THREADS, unsigned int capacity=2*1024*1024) : maxThreads{maxThreads}, capacity{capacity} {
buckets = new Node[capacity];
}
~TMHashMap() {
delete[] buckets;
}
std::string className() { return TM_NAME() + "-HashMap"; }
/*
* Progress Condition: lock-free
* Adds a node with a key if the key is not present, otherwise replaces the value.
* Returns the previous value (nullptr by default).
*/
V* put(K* key, V* value, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
if (value == nullptr) throw std::invalid_argument("value can not be nullptr");
V* oldVal = nullptr;
KeyVal *firstFree = nullptr;
auto h = std::hash<K>{}(*key);
Node* node = &buckets[h];
while (true) {
for (int i = 0; i < KV_NUM; i++) {
KeyVal& kv = node->kv[i];
if (kv.key == nullptr) {
// Save the first available entry, in case we need to insert somewhere
if (firstFree == nullptr) firstFree = &kv;
continue;
}
if (*kv.key != *key) continue;
// Found a matching key, replace the old value with the new
oldVal = kv.val;
kv.val = value;
return oldVal;
}
Node* lnext = node->next;
if (lnext == nullptr) break;
node = lnext;
}
// We got here without a replacement, so insert in the first available
if (firstFree == nullptr) {
// No available entry, allocate a node and insert it there
Node* newNode = TM_ALLOC<Node>(key,value);
node->next = newNode;
} else {
firstFree->key = key;
firstFree->val = value;
}
return oldVal;
}
/*
* Progress Condition: lock-free
* Removes a key, returning the value associated with it.
* Returns nullptr if there is no matching key.
*/
V* removeKey(K* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
auto h = std::hash<K>{}(*key);
Node* node = &buckets[h];
Node* prev = node;
while (true) {
for (int i = 0; i < KV_NUM; i++) {
KeyVal& kv = node->kv[i];
if (kv.key == nullptr || *kv.key != *key) continue;
// Found a matching key, replace the old value with nullptr
V* oldVal = kv.val;
kv.val = nullptr;
kv.key = nullptr;
// Check if it's the first node and if it is empty, then unlink it and free it
if (prev != node && node->isEmpty()) {
prev->next = node->next;
TM_FREE(node);
}
return oldVal;
}
prev = node;
node = node->next;
// We got to the end without a matching key, return nullptr
if (node == nullptr) return nullptr;
}
}
/*
* Progress Condition: lock-free
* Returns the value of associated with the key, nullptr if there is no mapping
*/
V* get(K* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
auto h = std::hash<K>{}(*key);
Node* node = &buckets[h];
while (true) {
for (int i = 0; i < KV_NUM; i++) {
KeyVal& kv = node->kv[i];
if (kv.key == nullptr || *kv.key != *key) continue;
return kv.val;
}
Node* lnext = node->next;
if (lnext == nullptr) return nullptr;
node = lnext;
}
}
//
// Set methods for running the usual tests and benchmarks
//
bool add(K* key, const int tid) {
return TM_WRITE_TRANSACTION<bool>([&] () -> bool {
return put(key,key, tid) == nullptr;
});
}
bool remove(K* key, const int tid) {
return TM_WRITE_TRANSACTION<bool>([this,key,tid] () -> bool {
return removeKey(key, tid) != nullptr;
});
}
bool contains(K* key, const int tid) {
return TM_READ_TRANSACTION<bool>([this,key,tid] () -> bool {
return get(key, tid) != nullptr;
});
}
// Used only for benchmarks. It's single-threaded
bool addAll(K** keys, const int size, const int tid) {
for (int i = 0; i < size; i++) add(keys[i], tid);
}
};
#endif /* _TM_NON_RESIZABLE_HASH_MAP_H_ */
================================================
FILE: datastructures/generic/TMLinkedListQueue.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2017, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _TM_LINKED_LIST_QUEUE_H_
#define _TM_LINKED_LIST_QUEUE_H_
#include <atomic>
#include <stdexcept>
#include "../../stms/CRWWPSTM.hpp"
#include "../../stms/LeftRightTM.hpp"
#include "../../stms/tm.h" // This header defines the macros for the STM being compiled
#include "MWCLF.hpp"
#include "MWCWF.hpp"
#include "CXTM.hpp"
/**
* <h1> A Linked List queue using STM </h1>
*
*
* TODO
*
*
* enqueue algorithm: sequential implementation + MWC
* dequeue algorithm: sequential implementation + MWC
* Consistency: Linearizable
* enqueue() progress: lock-free
* dequeue() progress: lock-free
* Memory Reclamation: Hazard Eras (integrated into MWC)
* enqueue min ops: 2 DCAS + 1 CAS
* dequeue min ops: 1 DCAS + 1 CAS
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class TMLinkedListQueue {
private:
static const unsigned int MAX_THREADS = 128;
const unsigned int maxThreads;
struct Node : TM_BASE_TYPE {
T* item;
TM_TYPE<Node*> next;
Node(T* userItem) : item{userItem}, next{nullptr} { }
};
alignas(128) TM_TYPE<Node*> head {nullptr};
alignas(128) TM_TYPE<Node*> tail {nullptr};
public:
TMLinkedListQueue(unsigned int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
Node* sentinelNode = TM_ALLOC<Node>(nullptr);
head = sentinelNode;
tail = sentinelNode;
}
~TMLinkedListQueue() {
// TODO: replace this 0 with the actual tid otherwise we could have issues
while (dequeue(0) != nullptr); // Drain the queue
Node* lhead = head;
delete lhead;
}
static std::string className() { return TM_NAME() + "-LinkedListQueue"; }
/*
*
* Always returns true
*/
bool enqueue(T* item, const int tid) {
if (item == nullptr) throw std::invalid_argument("item can not be nullptr");
return TM_WRITE_TRANSACTION<bool>([this,item] () -> bool {
Node* newNode = TM_ALLOC<Node>(item);
tail->next = newNode;
tail = newNode;
return true;
});
}
/*
*
*/
T* dequeue(const int tid) {
return TM_WRITE_TRANSACTION<T*>([this] () -> T* {
Node* lhead = head;
if (lhead == tail) return nullptr;
head = lhead->next;
TM_FREE(lhead);
return head->item;
});
}
};
#endif /* _MWC_LINKED_LIST_QUEUE_H_ */
================================================
FILE: datastructures/generic/TMLinkedListSet.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2018, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _TM_LINKED_LIST_SET_H_
#define _TM_LINKED_LIST_SET_H_
#include <atomic>
#include <stdexcept>
#include "../../stms/tm.h" // This header defines the macros for the STM being compiled
/**
* <h1> A Linked List Set for usage with STMs </h1>
*
* TODO
*
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class TMLinkedListSet : public TM_BASE_TYPE {
private:
static const unsigned int MAX_THREADS = 128;
const unsigned int maxThreads;
struct Node : public TM_BASE_TYPE {
T* key;
TM_TYPE<Node*> next;
Node(T* key) : key{key}, next{nullptr} { }
};
alignas(128) TM_TYPE<Node*> head {nullptr};
alignas(128) TM_TYPE<Node*> tail {nullptr};
public:
TMLinkedListSet(unsigned int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
Node* lhead = new Node(nullptr);
Node* ltail = new Node(nullptr);
head = lhead;
head->next = ltail;
tail = ltail;
}
~TMLinkedListSet() {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
delete prev;
prev = node;
node = node->next;
}
delete prev;
delete tail;
}
static std::string className() { return TM_NAME() + "-LinkedListSet"; }
#ifdef TINY_STM
/*
* Progress Condition: lock-free
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
bool retval = false;
WRITE_TX_BEGIN
Node* newNode = TM_ALLOC<Node>(key);
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) {
prev->next = newNode;
newNode->next = node;
retval = true;
break;
}
if (*key == *node->key) {
TM_FREE(newNode); // If the key was already in the set, free the node that was never used
break;
}
if (*(node->key) < *key) {
prev->next = newNode;
newNode->next = node;
retval = true;
break;
}
prev = node;
node = node->next;
}
WRITE_TX_END
return retval;
}
/*
* Progress Condition: lock-free
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
bool retval = false;
WRITE_TX_BEGIN
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) break;
if (*key == *node->key) {
prev->next = node->next;
TM_FREE(node);
retval = true;
break;
}
if (*(node->key) < *key) break;
prev = node;
node = node->next;
}
WRITE_TX_END
return retval;
}
/*
* Progress Condition: lock-free
* Returns true if it finds a node with a matching key
*/
bool contains(T* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
bool retval = false;
READ_TX_BEGIN
Node* node = head->next;
while (true) {
if (node == tail) break;
if (*key == *node->key) {retval = true; break; }
if (*(node->key) < *key) break;
node = node->next;
}
READ_TX_END
return retval;
}
#else
/*
* Progress Condition: lock-free
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
return TM_WRITE_TRANSACTION<bool>([this,key] () -> bool {
Node* newNode = TM_ALLOC<Node>(key);
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) break;
if (*key == *node->key) {
TM_FREE(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (*(node->key) < *key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: lock-free
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
return TM_WRITE_TRANSACTION<bool>([this,key] () -> bool {
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) return false;
if (*key == *node->key) {
prev->next = node->next;
TM_FREE(node);
return true;
}
if (*(node->key) < *key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: lock-free
* Returns true if it finds a node with a matching key
*/
bool contains(T* key, const int tid) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
return TM_READ_TRANSACTION<bool>([this,key] () -> bool {
Node* node = head->next;
while (true) {
if (node == tail) return false;
if (*key == *node->key) return true;
if (*(node->key) < *key) return false;
node = node->next;
}
});
}
#endif
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(keys[i], tid);
}
};
#endif /* _TM_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/generic/TMRedBlackBST.hpp
================================================
#ifndef _TM_RED_BLACK_BST_H_
#define _TM_RED_BLACK_BST_H_
#include <cassert>
#include <stdexcept>
#include <algorithm>
#include "../../stms/tm.h" // This header defines the macros for the STM being compiled
static const int64_t RED = 0;
static const int64_t BLACK = 1;
//http://algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/RedBlackBST.java
template<typename K, typename V>
class TMRedBlackBST : public TM_BASE_TYPE {
struct Node : TM_BASE_TYPE {
TM_TYPE<K*> key;
TM_TYPE<V*> val;
TM_TYPE<Node*> left {nullptr};
TM_TYPE<Node*> right {nullptr};
TM_TYPE<int64_t> color; // color of parent link
TM_TYPE<int64_t> size; // subtree count
Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{val}, color{color}, size{size} {}
};
TM_TYPE<Node*> root {nullptr}; // root of the BST
const unsigned int maxThreads;
inline void assignAndFreeIfNull(TM_TYPE<Node*>& z, Node* w) {
Node* tofree = z;
z = w;
if (w == nullptr) TM_FREE(tofree);
}
public:
/**
* Initializes an empty symbol table.
*/
TMRedBlackBST(unsigned int maxThreads=128) : maxThreads{maxThreads} { }
/***************************************************************************
* Node helper methods.
***************************************************************************/
// is node x red; false if x is null ?
bool isRed(Node* x) {
if (x == nullptr) return false;
return x->color == RED;
}
// number of node in subtree rooted at x; 0 if x is null
int size(Node* x) {
if (x == nullptr) return 0;
return x->size;
}
/**
* Returns the number of key-value pairs in this symbol table.
* @return the number of key-value pairs in this symbol table
*/
int size() {
return size(root);
}
/**
* Is this symbol table empty?
* @return {@code true} if this symbol table is empty and {@code false} otherwise
*/
bool isEmpty() {
return root == nullptr;
}
/***************************************************************************
* Standard BST search->
***************************************************************************/
/**
* Returns the value associated with the given key.
* @param key the key
* @return the value associated with the given key if the key is in the symbol table
* and {@code null} if the key is not in the symbol table
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
V* get(K* key) {
if (key == nullptr) throw std::invalid_argument("item can not be nullptr");
return get(root, key);
}
// value associated with the given key in subtree rooted at x; null if no such key
V* get(Node* x, K* key) {
while (x != nullptr) {
if (*key < *x->key) x = x->left;
else if (*x->key < *key) x = x->right;
else return x->val;
}
return nullptr;
}
/**
* Does this symbol table contain the given key?
* @param key the key
* @return {@code true} if this symbol table contains {@code key} and
* {@code false} otherwise
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
bool contains(K* key) {
return get(key) != nullptr;
}
/***************************************************************************
* Red-black tree insertion.
***************************************************************************/
/**
* Inserts the specified key-value pair into the symbol table, overwriting the old
* value with the new value if the symbol table already contains the specified key.
* Deletes the specified key (and its associated value) from this symbol table
* if the specified value is {@code null}.
*
* @param key the key
* @param val the value
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
void put(K* key, V* val) {
if (key == nullptr) throw std::invalid_argument("item can not be nullptr");
if (val == nullptr) {
deleteKey(key);
return;
}
root = put(root, key, val);
root->color = BLACK;
// assert check();
}
// insert the key-value pair in the subtree rooted at h
Node* put(Node* h, K* key, V* val) {
if (h == nullptr) return TM_ALLOC<Node>(key, val, RED, 1);
if (*key < *h->key) h->left = put(h->left, key, val);
else if (*h->key < *key) h->right = put(h->right, key, val);
else h->val = val;
// fix-up any right-leaning links
if (isRed(h->right) && !isRed(h->left)) h = rotateLeft(h);
if (isRed(h->left) && isRed(h->left->left)) h = rotateRight(h);
if (isRed(h->left) && isRed(h->right)) flipColors(h);
h->size = size(h->left) + size(h->right) + 1;
return h;
}
/***************************************************************************
* Red-black tree deletion.
***************************************************************************/
/**
* Removes the smallest key and associated value from the symbol table.
* @throws NoSuchElementException if the symbol table is empty
*/
void deleteMin() {
if (isEmpty()) throw std::invalid_argument("item can not be nullptr");
// if both children of root are black, set root to red
if (!isRed(root->left) && !isRed(root->right))
root->color = RED;
assignAndFreeIfNull(root, deleteMin(root));
if (!isEmpty()) root->color = BLACK;
// assert check();
}
// delete the key-value pair with the minimum key rooted at h
Node* deleteMin(Node* h) {
if (h->left == nullptr)
return nullptr;
if (!isRed(h->left) && !isRed(h->left->left))
h = moveRedLeft(h);
assignAndFreeIfNull(h->left, deleteMin(h->left));
return balance(h);
}
/**
* Removes the largest key and associated value from the symbol table.
* @throws NoSuchElementException if the symbol table is empty
*/
void deleteMax() {
if (isEmpty()) throw std::invalid_argument("item can not be nullptr");
// if both children of root are black, set root to red
if (!isRed(root->left) && !isRed(root->right))
root->color = RED;
root = deleteMax(root);
if (!isEmpty()) root->color = BLACK;
// assert check();
}
// delete the key-value pair with the maximum key rooted at h
Node* deleteMax(Node* h) {
if (isRed(h->left))
h = rotateRight(h);
if (h->right == nullptr)
return nullptr;
if (!isRed(h->right) && !isRed(h->right->left))
h = moveRedRight(h);
h->right = deleteMax(h->right);
return balance(h);
}
/**
* Removes the specified key and its associated value from this symbol table
* (if the key is in this symbol table).
*
* @param key the key
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
void deleteKey(K* key) {
if (key == nullptr) throw std::invalid_argument("item can not be nullptr");
if (!contains(key)) return;
// if both children of root are black, set root to red
if (!isRed(root->left) && !isRed(root->right))
root->color = RED;
assignAndFreeIfNull(root, deleteKey(root, key));
if (!isEmpty()) root->color = BLACK;
// assert check();
}
// delete the key-value pair with the given key rooted at h
Node* deleteKey(Node* h, K* key) {
// assert get(h, key) != null;
if (*key < *h->key) {
if (!isRed(h->left) && !isRed(h->left->left)) {
h = moveRedLeft(h);
}
assignAndFreeIfNull(h->left, deleteKey(h->left, key));
} else {
if (isRed(h->left)) {
h = rotateRight(h);
}
if (*key == *h->key && (h->right == nullptr)) {
return nullptr;
}
if (!isRed(h->right) && !isRed(h->right->left)) {
h = moveRedRight(h);
}
if (*key == *h->key) {
Node* x = min(h->right);
h->key = x->key;
h->val = x->val;
// h->val = get(h->right, min(h->right).key);
// h->key = min(h->right).key;
assignAndFreeIfNull(h->right, deleteMin(h->right));
} else {
assignAndFreeIfNull(h->right, deleteKey(h->right, key));
}
}
return balance(h);
}
/***************************************************************************
* Red-black tree helper functions.
***************************************************************************/
// make a left-leaning link lean to the right
Node* rotateRight(Node* h) {
// assert (h != null) && isRed(h->left);
Node* x = h->left;
h->left = x->right;
x->right = h;
x->color = x->right->color;
x->right->color = RED;
x->size = h->size;
h->size = size(h->left) + size(h->right) + 1;
return x;
}
// make a right-leaning link lean to the left
Node* rotateLeft(Node* h) {
// assert (h != null) && isRed(h->right);
Node* x = h->right;
h->right = x->left;
x->left = h;
x->color = x->left->color;
x->left->color = RED;
x->size = h->size;
h->size = size(h->left) + size(h->right) + 1;
return x;
}
// flip the colors of a node and its two children
void flipColors(Node* h) {
// h must have opposite color of its two children
// assert (h != null) && (h->left != null) && (h->right != null);
// assert (!isRed(h) && isRed(h->left) && isRed(h->right))
// || (isRed(h) && !isRed(h->left) && !isRed(h->right));
h->color = !h->color;
h->left->color = !h->left->color;
h->right->color = !h->right->color;
}
// Assuming that h is red and both h->left and h->left.left
// are black, make h->left or one of its children red.
Node* moveRedLeft(Node* h) {
// assert (h != null);
// assert isRed(h) && !isRed(h->left) && !isRed(h->left.left);
flipColors(h);
if (isRed(h->right->left)) {
h->right = rotateRight(h->right);
h = rotateLeft(h);
flipColors(h);
}
return h;
}
// Assuming that h is red and both h->right and h->right.left
// are black, make h->right or one of its children red.
Node* moveRedRight(Node* h) {
// assert (h != null);
// assert isRed(h) && !isRed(h->right) && !isRed(h->right.left);
flipColors(h);
if (isRed(h->left->left)) {
h = rotateRight(h);
flipColors(h);
}
return h;
}
// restore red-black tree invariant
Node* balance(Node* h) {
// assert (h != null);
if (isRed(h->right)) h = rotateLeft(h);
if (isRed(h->left) && isRed(h->left->left)) h = rotateRight(h);
if (isRed(h->left) && isRed(h->right)) flipColors(h);
h->size = size(h->left) + size(h->right) + 1;
return h;
}
/***************************************************************************
* Utility functions.
***************************************************************************/
/**
* Returns the height of the BST (for debugging).
* @return the height of the BST (a 1-node tree has height 0)
*/
int height() {
return height(root);
}
int height(Node* x) {
if (x == nullptr) return -1;
return 1 + std::max(height(x->left), height(x->right));
}
/***************************************************************************
* Ordered symbol table methods.
***************************************************************************/
/**
* Returns the smallest key in the symbol table.
* @return the smallest key in the symbol table
* @throws NoSuchElementException if the symbol table is empty
*/
K* min() {
if (isEmpty()) throw std::invalid_argument("item can not be nullptr");
return min(root).key;
}
// the smallest key in subtree rooted at x; null if no such key
Node* min(Node* x) {
// assert x != null;
if (x->left == nullptr) return x;
else return min(x->left);
}
/**
* Returns the largest key in the symbol table.
* @return the largest key in the symbol table
* @throws NoSuchElementException if the symbol table is empty
*/
K* max() {
if (isEmpty()) throw std::invalid_argument("item can not be nullptr");
return max(root).key;
}
// the largest key in the subtree rooted at x; null if no such key
Node* max(Node* x) {
// assert x != null;
if (x->right == nullptr) return x;
else return max(x->right);
}
/**
* Returns the largest key in the symbol table less than or equal to {@code key}.
* @param key the key
* @return the largest key in the symbol table less than or equal to {@code key}
* @throws NoSuchElementException if there is no such key
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
K* floor(K* key) {
if (key == nullptr) throw std::invalid_argument("item can not be nullptr");
if (isEmpty()) throw std::invalid_argument("item can not be nullptr");
Node* x = floor(root, key);
if (x == nullptr) return nullptr;
else return x->key;
}
// the largest key in the subtree rooted at x less than or equal to the given key
Node* floor(Node* x, K* key) {
if (x == nullptr) return nullptr;
if (*key == *x->key) return x;
if (*key < *x->key) return floor(x->left, key);
Node* t = floor(x->right, key);
if (t != nullptr) return t;
else return x;
}
/**
* Returns the smallest key in the symbol table greater than or equal to {@code key}.
* @param key the key
* @return the smallest key in the symbol table greater than or equal to {@code key}
* @throws NoSuchElementException if there is no such key
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
K* ceiling(K* key) {
if (key == nullptr) throw std::invalid_argument("item can not be nullptr");
if (isEmpty()) throw std::invalid_argument("item can not be nullptr");
Node* x = ceiling(root, key);
if (x == nullptr) return nullptr;
else return x->key;
}
// the smallest key in the subtree rooted at x greater than or equal to the given key
Node* ceiling(Node* x, K* key) {
if (x == nullptr) return nullptr;
if (*key == *x->key) return x;
if (*x->key < *key) return ceiling(x->right, key);
Node* t = ceiling(x->left, key);
if (t != nullptr) return t;
else return x;
}
/**
* Return the kth smallest key in the symbol table.
* @param k the order statistic
* @return the {@code k}th smallest key in the symbol table
* @throws IllegalArgumentException unless {@code k} is between 0 and
* <em>n</em>1
*/
K* select(int k) {
if (k < 0 || k >= size()) {
throw std::invalid_argument("item can not be nullptr");
}
Node x = select(root, k);
return x->key;
}
// the key of rank k in the subtree rooted at x
Node* select(Node* x, int k) {
// assert x != null;
// assert k >= 0 && k < size(x);
int t = size(x->left);
if (t > k) return select(x->left, k);
else if (t < k) return select(x->right, k-t-1);
else return x;
}
/**
* Return the number of keys in the symbol table strictly less than {@code key}.
* @param key the key
* @return the number of keys in the symbol table strictly less than {@code key}
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
int rank(K* key) {
if (key == nullptr) throw std::invalid_argument("item can not be nullptr");
return rank(key, root);
}
// number of keys less than key in the subtree rooted at x
int rank(K* key, Node* x) {
if (x == nullptr) return 0;
if (*key < *x->key) return rank(key, x->left);
else if (*x->key < *key) return 1 + size(x->left) + rank(key, x->right);
else return size(x->left);
}
/***************************************************************************
* Range count and range search->
***************************************************************************/
/**
* Returns the number of keys in the symbol table in the given range.
*
* @param lo minimum endpoint
* @param hi maximum endpoint
* @return the number of keys in the sybol table between {@code lo}
* (inclusive) and {@code hi} (inclusive)
* @throws IllegalArgumentException if either {@code lo} or {@code hi}
* is {@code null}
*/
int size(K* lo, K* hi) {
if (lo == nullptr) throw std::invalid_argument("item can not be nullptr");
if (hi == nullptr) throw std::invalid_argument("item can not be nullptr");
if (*hi < *lo) return 0;
if (contains(hi)) return rank(hi) - rank(lo) + 1;
else return rank(hi) - rank(lo);
}
/***************************************************************************
* Check integrity of red-black tree data structure.
***************************************************************************/
bool check() {
if (!isBST()) std::cout << "Not in symmetric order\n";
if (!isSizeConsistent()) std::cout << "Subtree counts not consistent\n";
//if (!isRankConsistent()) std::cout << "Ranks not consistent\n";
if (!is23()) std::cout << "Not a 2-3 tree\n";
if (!isBalanced()) std::cout << "Not balanced\n";
return isBST() && isSizeConsistent() && is23() && isBalanced();
}
// does this binary tree satisfy symmetric order?
// Note: this test also ensures that data structure is a binary tree since order is strict
bool isBST() {
return isBST(root, nullptr, nullptr);
}
// is the tree rooted at x a BST with all keys strictly between min and max
// (if min or max is null, treat as empty constraint)
// Credit: Bob Dondero's elegant solution
bool isBST(Node* x, K* min, K* max) {
if (x == nullptr) return true;
// TODO: port these two lines
//if (min != nullptr && x->key.compareTo(min) <= 0) return false;
//if (max != nullptr && x->key.compareTo(max) >= 0) return false;
return isBST(x->left, min, x->key) && isBST(x->right, x->key, max);
}
// are the size fields correct?
bool isSizeConsistent() { return isSizeConsistent(root); }
bool isSizeConsistent(Node* x) {
if (x == nullptr) return true;
if (x->size != size(x->left) + size(x->right) + 1) return false;
return isSizeConsistent(x->left) && isSizeConsistent(x->right);
}
/*
// check that ranks are consistent
bool isRankConsistent() {
for (int i = 0; i < size(); i++)
if (i != rank(select(i))) return false;
for (K* key : keys())
if (key.compareTo(select(rank(key))) != 0) return false;
return true;
}
*/
// Does the tree have no red right links, and at most one (left)
// red links in a row on any path?
bool is23() { return is23(root); }
bool is23(Node* x) {
if (x == nullptr) return true;
if (isRed(x->right)) return false;
if (x != root && isRed(x) && isRed(x->left))
return false;
return is23(x->left) && is23(x->right);
}
// do all paths from root to leaf have same number of black edges?
bool isBalanced() {
int black = 0; // number of black links on path from root to min
Node x = root;
while (x != nullptr) {
if (!isRed(x)) black++;
x = x->left;
}
return isBalanced(root, black);
}
// does every path from the root to a leaf have the given number of black links?
bool isBalanced(Node* x, int black) {
if (x == nullptr) return black == 0;
if (!isRed(x)) black--;
return isBalanced(x->left, black) && isBalanced(x->right, black);
}
// Set methods
bool add(K* key, const int tid) {
return TM_WRITE_TRANSACTION<bool>([this,key] () -> bool {
if (contains(key)) return false;
put(key,key);
return true;
});
}
bool remove(K* key, const int tid) {
return TM_WRITE_TRANSACTION<bool>([this,key] () -> bool {
if (!contains(key)) return false;
deleteKey(key);
return true;
});
}
inline bool contains(K* key, const int tid) {
return TM_READ_TRANSACTION<bool>([this,key] () -> bool {
return contains(key);
});
}
// This is not fully transactionally but it's ok because we use it only on initialization.
// We could make it fully transactionally, but we would have to increase the size of allocation/store logs.
bool addAll(K** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(keys[i], tid);
}
std::string className() { return TM_NAME() + "-RedBlackBST"; }
};
#endif // _TM_RED_BLACK_BST_H_
================================================
FILE: datastructures/hashmaps/CRWWPSTMResizableHashSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _CRWWP_STM_RESIZABLE_HASH_MAP_H_
#define _CRWWP_STM_RESIZABLE_HASH_MAP_H_
#include <string>
#include "stms/CRWWPSTM.hpp"
/**
* <h1> A Resizable Hash Map for usage with STMs </h1>
* TODO
*
*/
template<typename K>
class CRWWPSTMResizableHashSet {
private:
struct Node : public crwwpstm::tmbase {
crwwpstm::tmtype<K> key;
crwwpstm::tmtype<Node*> next {nullptr};
Node(const K& k) : key{k} { } // Copy constructor for k
};
crwwpstm::tmtype<long> capacity;
crwwpstm::tmtype<long> sizeHM = 0;
static constexpr double loadFactor = 0.75;
crwwpstm::tmtype<crwwpstm::tmtype<Node*>*> buckets; // An array of pointers to Nodes
public:
CRWWPSTMResizableHashSet(int maxThreads=0, int capacity=4) : capacity{capacity} {
crwwpstm::updateTx([&] () {
buckets = (crwwpstm::tmtype<Node*>*)crwwpstm::tmMalloc(capacity*sizeof(crwwpstm::tmtype<Node*>));
for (int i = 0; i < capacity; i++) buckets[i] = nullptr;
});
}
~CRWWPSTMResizableHashSet() {
crwwpstm::updateTx([&] () {
for(int i = 0; i < capacity; i++){
Node* node = buckets[i];
while (node != nullptr) {
Node* next = node->next;
crwwpstm::tmDelete(node);
node = next;
}
}
crwwpstm::tmFree(buckets.load());
});
}
static std::string className() { return crwwpstm::CRWWPSTM::className() + "-HashMap"; }
void rebuild() {
int newcapacity = 2*capacity;
crwwpstm::tmtype<Node*>* newbuckets = (crwwpstm::tmtype<Node*>*)crwwpstm::tmMalloc(newcapacity*sizeof(crwwpstm::tmtype<Node*>));
for (int i = 0; i < newcapacity; i++) newbuckets[i] = nullptr;
for (int i = 0; i < capacity; i++) {
Node* node = buckets[i];
while(node!=nullptr){
Node* next = node->next;
auto h = std::hash<K>{}(node->key) % newcapacity;
node->next = newbuckets[h];
newbuckets[h] = node;
node = next;
}
}
crwwpstm::tmFree(buckets.load());
buckets = newbuckets;
capacity = newcapacity;
}
/*
* Adds a node with a key if the key is not present, otherwise replaces the value.
* If saveOldValue is set, it will set 'oldValue' to the previous value, iff there was already a mapping.
*
* Returns true if there was no mapping for the key, false if there was already a value and it was replaced.
*/
bool innerPut(const K& key) {
if (sizeHM > capacity*loadFactor) rebuild();
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) {
Node* newnode = crwwpstm::tmNew<Node>(key);
if (node == prev) {
buckets[h] = newnode;
} else {
prev->next = newnode;
}
sizeHM++;
return true; // New insertion
}
if (key == node->key) return false;
prev = node;
node = node->next;
}
}
/*
* Removes a key and its mapping.
* Saves the value in 'oldvalue' if 'saveOldValue' is set.
*
* Returns returns true if a matching key was found
*/
bool innerRemove(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) return false;
if (key == node->key) {
if (node == prev) {
buckets[h] = node->next;
} else {
prev->next = node->next;
}
sizeHM--;
crwwpstm::tmDelete(node);
return true;
}
prev = node;
node = node->next;
}
}
/*
* Returns true if key is present. Saves a copy of 'value' in 'oldValue' if 'saveOldValue' is set.
*/
bool innerGet(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
while (true) {
if (node == nullptr) return false;
if (key == node->key) return true;
node = node->next;
}
}
//
// Set methods for running the usual tests and benchmarks
//
// Inserts a key only if it's not already present
bool add(K key, const int tid=0) {
return crwwpstm::updateTx<bool>([&] () {
return innerPut(key);
});
}
// Returns true only if the key was present
bool remove(K key, const int tid=0) {
return crwwpstm::updateTx<bool>([&] () {
return innerRemove(key);
});
}
bool contains(K key, const int tid=0) {
return crwwpstm::readTx<bool>([&] () {
return innerGet(key);
});
}
// Used only for benchmarks
void addAll(K** keys, const int size, const int tid=0) {
for (int i = 0; i < size; i++) add(*keys[i]);
}
};
#endif /* _CRWWP_STM_RESIZABLE_HASH_MAP_H_ */
================================================
FILE: datastructures/hashmaps/ESTMResizableHashSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _ESTM_RESIZABLE_HASH_MAP_H_
#define _ESTM_RESIZABLE_HASH_MAP_H_
#include <string>
#include "stms/ESTM.hpp"
/**
* <h1> A Resizable Hash Map for usage with STMs </h1>
* TODO
*
*/
template<typename K>
class ESTMResizableHashSet {
private:
struct Node : public estm::tmbase {
estm::tmtype<K> key;
estm::tmtype<Node*> next {nullptr};
Node(const K& k) : key{k} { } // Copy constructor for k
};
estm::tmtype<uint64_t> capacity;
estm::tmtype<uint64_t> sizeHM = 0;
static constexpr double loadFactor = 0.75;
estm::tmtype<estm::tmtype<Node*>*> buckets; // An array of pointers to Nodes
public:
ESTMResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity{capacity} {
estm::updateTx([&] () {
buckets = (estm::tmtype<Node*>*)estm::tmMalloc(capacity*sizeof(estm::tmtype<Node*>));
for (int i = 0; i < capacity; i++) buckets[i] = nullptr;
});
}
~ESTMResizableHashSet() {
estm::updateTx([&] () {
for(int i = 0; i < capacity; i++){
Node* node = buckets[i];
while (node != nullptr) {
Node* next = node->next;
estm::tmDelete(node);
node = next;
}
}
estm::tmFree(buckets.load());
});
}
static std::string className() { return estm::ESTM::className() + "-HashMap"; }
void rebuild() {
uint64_t newcapacity = 2*capacity;
estm::tmtype<Node*>* newbuckets = (estm::tmtype<Node*>*)estm::tmMalloc(newcapacity*sizeof(estm::tmtype<Node*>));
for (int i = 0; i < newcapacity; i++) newbuckets[i] = nullptr;
for (int i = 0; i < capacity; i++) {
Node* node = buckets[i];
while (node!=nullptr) {
Node* next = node->next;
auto h = std::hash<K>{}(node->key) % newcapacity;
node->next = newbuckets[h];
newbuckets[h] = node;
node = next;
}
}
estm::tmFree(buckets);
buckets = newbuckets;
capacity = newcapacity;
}
/*
* Adds a node with a key if the key is not present, otherwise replaces the value.
* If saveOldValue is set, it will set 'oldValue' to the previous value, iff there was already a mapping.
*
* Returns true if there was no mapping for the key, false if there was already a value and it was replaced.
*/
bool innerPut(const K& key) {
if (sizeHM.load() > capacity.load()*loadFactor) rebuild();
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) {
Node* newnode = estm::tmNew<Node>(key);
if (node == prev) {
buckets[h] = newnode;
} else {
prev->next = newnode;
}
sizeHM++;
return true; // New insertion
}
if (key == node->key) return false;
prev = node;
node = node->next;
}
}
/*
* Removes a key and its mapping.
* Saves the value in 'oldvalue' if 'saveOldValue' is set.
*
* Returns returns true if a matching key was found
*/
bool innerRemove(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) return false;
if (key == node->key) {
if (node == prev) {
buckets[h] = node->next;
} else {
prev->next = node->next;
}
sizeHM--;
estm::tmDelete(node);
return true;
}
prev = node;
node = node->next;
}
}
/*
* Returns true if key is present. Saves a copy of 'value' in 'oldValue' if 'saveOldValue' is set.
*/
bool innerGet(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
while (true) {
if (node == nullptr) return false;
if (key == node->key) return true;
node = node->next;
}
}
//
// Set methods for running the usual tests and benchmarks
//
// Inserts a key only if it's not already present
bool add(K key, const int tid=0) {
return estm::updateTx<bool>([&] () {
return innerPut(key);
});
}
// Returns true only if the key was present
bool remove(K key, const int tid=0) {
return estm::updateTx<bool>([&] () {
return innerRemove(key);
});
}
bool contains(K key, const int tid=0) {
return estm::readTx<bool>([&] () {
return innerGet(key);
});
}
// Used only for benchmarks
void addAll(K** keys, const int size, const int tid=0) {
for (int i = 0; i < size; i++) add(*keys[i]);
}
};
#endif /* _ESTM_RESIZABLE_HASH_MAP_H_ */
================================================
FILE: datastructures/hashmaps/OFLFResizableHashSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _OF_LF_RESIZABLE_HASH_MAP_H_
#define _OF_LF_RESIZABLE_HASH_MAP_H_
#include <string>
#include "stms/OneFileLF.hpp"
/**
* <h1> A Resizable Hash Map for usage with STMs </h1>
* TODO
*
*/
template<typename K>
class OFLFResizableHashSet {
private:
struct Node : public oflf::tmbase {
oflf::tmtype<K> key;
oflf::tmtype<Node*> next {nullptr};
Node(const K& k) : key{k} { } // Copy constructor for k
};
oflf::tmtype<uint64_t> capacity;
oflf::tmtype<uint64_t> sizeHM = 0;
static constexpr double loadFactor = 0.75;
oflf::tmtype<oflf::tmtype<Node*>*> buckets; // An array of pointers to Nodes
public:
OFLFResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity{capacity} {
oflf::updateTx([&] () {
buckets = (oflf::tmtype<Node*>*)oflf::tmMalloc(capacity*sizeof(oflf::tmtype<Node*>));
for (int i = 0; i < capacity; i++) buckets[i] = nullptr;
});
}
~OFLFResizableHashSet() {
oflf::updateTx([&] () {
for (int i = 0; i < capacity; i++){
Node* node = buckets[i];
while (node != nullptr) {
Node* next = node->next;
oflf::tmDelete(node);
node = next;
}
}
oflf::tmFree(buckets.pload());
});
}
static std::string className() { return oflf::OneFileLF::className() + "-HashMap"; }
void rebuild() {
uint64_t newcapacity = 2*capacity;
oflf::tmtype<Node*>* newbuckets = (oflf::tmtype<Node*>*)oflf::tmMalloc(newcapacity*sizeof(oflf::tmtype<Node*>));
for (int i = 0; i < newcapacity; i++) newbuckets[i] = nullptr;
for (int i = 0; i < capacity; i++) {
Node* node = buckets[i];
while (node!=nullptr) {
Node* next = node->next;
auto h = std::hash<K>{}(node->key) % newcapacity;
node->next = newbuckets[h];
newbuckets[h] = node;
node = next;
}
}
oflf::tmFree(buckets.pload());
buckets = newbuckets;
capacity = newcapacity;
}
/*
* Adds a node with a key if the key is not present, otherwise replaces the value.
* If saveOldValue is set, it will set 'oldValue' to the previous value, iff there was already a mapping.
*
* Returns true if there was no mapping for the key, false if there was already a value and it was replaced.
*/
bool innerPut(const K& key) {
if (sizeHM.pload() > capacity.pload()*loadFactor) rebuild();
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) {
Node* newnode = oflf::tmNew<Node>(key);
if (node == prev) {
buckets[h] = newnode;
} else {
prev->next = newnode;
}
sizeHM++;
return true; // New insertion
}
if (key == node->key) return false;
prev = node;
node = node->next;
}
}
/*
* Removes a key and its mapping.
* Saves the value in 'oldvalue' if 'saveOldValue' is set.
*
* Returns returns true if a matching key was found
*/
bool innerRemove(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) return false;
if (key == node->key) {
if (node == prev) {
buckets[h] = node->next;
} else {
prev->next = node->next;
}
sizeHM--;
oflf::tmDelete(node);
return true;
}
prev = node;
node = node->next;
}
}
/*
* Returns true if key is present. Saves a copy of 'value' in 'oldValue' if 'saveOldValue' is set.
*/
bool innerGet(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
while (true) {
if (node == nullptr) return false;
if (key == node->key) return true;
node = node->next;
}
}
//
// Set methods for running the usual tests and benchmarks
//
// Inserts a key only if it's not already present
bool add(K key, const int tid=0) {
return oflf::updateTx<bool>([&] () {
return innerPut(key);
});
}
// Returns true only if the key was present
bool remove(K key, const int tid=0) {
return oflf::updateTx<bool>([&] () {
return innerRemove(key);
});
}
bool contains(K key, const int tid=0) {
return oflf::readTx<bool>([&] () {
return innerGet(key);
});
}
// Used only for benchmarks
void addAll(K** keys, const int size, const int tid=0) {
for (int i = 0; i < size; i++) add(*keys[i]);
}
};
#endif /* _OF_LF_RESIZABLE_HASH_MAP_H_ */
================================================
FILE: datastructures/hashmaps/OFWFResizableHashSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _OF_WF_RESIZABLE_HASH_MAP_H_
#define _OF_WF_RESIZABLE_HASH_MAP_H_
#include <string>
#include "stms/OneFileWF.hpp"
/**
* <h1> A Resizable Hash Map for usage with STMs </h1>
* TODO
*
*/
template<typename K>
class OFWFResizableHashSet {
private:
struct Node : public ofwf::tmbase {
ofwf::tmtype<K> key;
ofwf::tmtype<Node*> next {nullptr};
Node(const K& k) : key{k} { } // Copy constructor for k
};
ofwf::tmtype<uint64_t> capacity;
ofwf::tmtype<uint64_t> sizeHM = 0;
static constexpr double loadFactor = 0.75;
ofwf::tmtype<ofwf::tmtype<Node*>*> buckets; // An array of pointers to Nodes
public:
OFWFResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity{capacity} {
ofwf::updateTx([&] () {
buckets = (ofwf::tmtype<Node*>*)ofwf::tmMalloc(capacity*sizeof(ofwf::tmtype<Node*>));
for (int i = 0; i < capacity; i++) buckets[i] = nullptr;
});
}
~OFWFResizableHashSet() {
ofwf::updateTx([=] () {
for (int i = 0; i < capacity; i++){
Node* node = buckets[i];
while (node != nullptr) {
Node* next = node->next;
ofwf::tmDelete(node);
node = next;
}
}
ofwf::tmFree(buckets.pload());
});
}
static std::string className() { return ofwf::OneFileWF::className() + "-HashMap"; }
void rebuild() {
uint64_t newcapacity = 2*capacity;
ofwf::tmtype<Node*>* newbuckets = (ofwf::tmtype<Node*>*)ofwf::tmMalloc(newcapacity*sizeof(ofwf::tmtype<Node*>));
for (int i = 0; i < newcapacity; i++) newbuckets[i] = nullptr;
for (int i = 0; i < capacity; i++) {
Node* node = buckets[i];
while (node!=nullptr) {
Node* next = node->next;
auto h = std::hash<K>{}(node->key) % newcapacity;
node->next = newbuckets[h];
newbuckets[h] = node;
node = next;
}
}
ofwf::tmFree(buckets.pload());
buckets = newbuckets;
capacity = newcapacity;
}
/*
* Adds a node with a key if the key is not present, otherwise replaces the value.
* If saveOldValue is set, it will set 'oldValue' to the previous value, iff there was already a mapping.
*
* Returns true if there was no mapping for the key, false if there was already a value and it was replaced.
*/
bool innerPut(const K& key) {
if (sizeHM.pload() > capacity.pload()*loadFactor) rebuild();
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) {
Node* newnode = ofwf::tmNew<Node>(key);
if (node == prev) {
buckets[h] = newnode;
} else {
prev->next = newnode;
}
sizeHM++;
return true; // New insertion
}
if (key == node->key) return false;
prev = node;
node = node->next;
}
}
/*
* Removes a key and its mapping.
* Saves the value in 'oldvalue' if 'saveOldValue' is set.
*
* Returns returns true if a matching key was found
*/
bool innerRemove(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) return false;
if (key == node->key) {
if (node == prev) {
buckets[h] = node->next;
} else {
prev->next = node->next;
}
sizeHM--;
ofwf::tmDelete(node);
return true;
}
prev = node;
node = node->next;
}
}
/*
* Returns true if key is present. Saves a copy of 'value' in 'oldValue' if 'saveOldValue' is set.
*/
bool innerGet(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
while (true) {
if (node == nullptr) return false;
if (key == node->key) return true;
node = node->next;
}
}
//
// Set methods for running the usual tests and benchmarks
//
// Inserts a key only if it's not already present
bool add(K key, const int tid=0) {
return ofwf::updateTx<bool>([=] () {
return innerPut(key);
});
}
// Returns true only if the key was present
bool remove(K key, const int tid=0) {
return ofwf::updateTx<bool>([=] () {
return innerRemove(key);
});
}
bool contains(K key, const int tid=0) {
return ofwf::readTx<bool>([=] () {
return innerGet(key);
});
}
// Used only for benchmarks
void addAll(K** keys, const int size, const int tid=0) {
for (int i = 0; i < size; i++) add(*keys[i]);
}
};
#endif /* _OF_WF_RESIZABLE_HASH_MAP_H_ */
================================================
FILE: datastructures/hashmaps/TinySTMResizableHashSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _TINY_STM_RESIZABLE_HASH_MAP_H_
#define _TINY_STM_RESIZABLE_HASH_MAP_H_
#include <string>
#include "stms/TinySTM.hpp"
/**
* <h1> A Resizable Hash Map for usage with STMs </h1>
* TODO
*
*/
template<typename K>
class TinySTMResizableHashSet {
private:
struct Node : public tinystm::tmbase {
tinystm::tmtype<K> key;
tinystm::tmtype<Node*> next {nullptr};
Node(const K& k) : key{k} { } // Copy constructor for k
};
tinystm::tmtype<uint64_t> capacity;
tinystm::tmtype<uint64_t> sizeHM = 0;
static constexpr double loadFactor = 0.75;
tinystm::tmtype<tinystm::tmtype<Node*>*> buckets; // An array of pointers to Nodes
public:
TinySTMResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity{capacity} {
tinystm::updateTx<bool>([&] () {
buckets = (tinystm::tmtype<Node*>*)tinystm::tmMalloc(capacity*sizeof(tinystm::tmtype<Node*>));
for (int i = 0; i < capacity; i++) buckets[i] = nullptr;
return true;
});
}
~TinySTMResizableHashSet() {
tinystm::updateTx<bool>([&] () {
for(int i = 0; i < capacity; i++){
Node* node = buckets[i];
while (node != nullptr) {
Node* next = node->next;
tinystm::tmDelete(node);
node = next;
}
}
tinystm::tmFree(buckets.load());
return true;
});
}
static std::string className() { return tinystm::TinySTM::className() + "-HashMap"; }
void rebuild() {
uint64_t newcapacity = 2*capacity;
tinystm::tmtype<Node*>* newbuckets = (tinystm::tmtype<Node*>*)tinystm::tmMalloc(newcapacity*sizeof(tinystm::tmtype<Node*>));
for (int i = 0; i < newcapacity; i++) newbuckets[i] = nullptr;
for (int i = 0; i < capacity; i++) {
Node* node = buckets[i];
while (node!=nullptr) {
Node* next = node->next;
auto h = std::hash<K>{}(node->key) % newcapacity;
node->next = newbuckets[h];
newbuckets[h] = node;
node = next;
}
}
tinystm::tmFree(buckets);
buckets = newbuckets;
capacity = newcapacity;
}
/*
* Adds a node with a key if the key is not present, otherwise replaces the value.
* If saveOldValue is set, it will set 'oldValue' to the previous value, iff there was already a mapping.
*
* Returns true if there was no mapping for the key, false if there was already a value and it was replaced.
*/
bool innerPut(const K& key) {
if (sizeHM > capacity*loadFactor) rebuild();
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) {
Node* newnode = tinystm::tmNew<Node>(key);
if (node == prev) {
buckets[h] = newnode;
} else {
prev->next = newnode;
}
sizeHM++;
return true; // New insertion
}
if (key == node->key) return false;
prev = node;
node = node->next;
}
}
/*
* Removes a key and its mapping.
* Saves the value in 'oldvalue' if 'saveOldValue' is set.
*
* Returns returns true if a matching key was found
*/
bool innerRemove(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
Node* prev = node;
while (true) {
if (node == nullptr) return false;
if (key == node->key) {
if (node == prev) {
buckets[h] = node->next;
} else {
prev->next = node->next;
}
sizeHM--;
tinystm::tmDelete(node);
return true;
}
prev = node;
node = node->next;
}
}
/*
* Returns true if key is present. Saves a copy of 'value' in 'oldValue' if 'saveOldValue' is set.
*/
bool innerGet(const K& key) {
auto h = std::hash<K>{}(key) % capacity;
Node* node = buckets[h];
while (true) {
if (node == nullptr) return false;
if (key == node->key) return true;
node = node->next;
}
}
//
// Set methods for running the usual tests and benchmarks
//
// Inserts a key only if it's not already present
bool add(K key, const int tid=0) {
return tinystm::updateTx<bool>([&] () {
return innerPut(key);
});
}
// Returns true only if the key was present
bool remove(K key, const int tid=0) {
return tinystm::updateTx<bool>([&] () {
return innerRemove(key);
});
}
bool contains(K key, const int tid=0) {
return tinystm::readTx<bool>([&] () {
return innerGet(key);
});
}
// Used only for benchmarks
void addAll(K** keys, const int size, const int tid=0) {
for (int i = 0; i < size; i++) add(*keys[i]);
}
};
#endif /* _TINY_STM_RESIZABLE_HASH_MAP_H_ */
================================================
FILE: datastructures/linkedlists/CRWWPLinkedListSet.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2018, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _CRWWP_STM_LINKED_LIST_SET_H_
#define _CRWWP_STM_LINKED_LIST_SET_H_
#include <atomic>
#include <stdexcept>
#include "stms/CRWWPSTM.hpp"
/**
* <h1> A Linked List Set for CRWWP STM (blocking) </h1>
*
* TODO
*
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class CRWWPLinkedListSet : public crwwpstm::tmbase {
private:
struct Node : public crwwpstm::tmbase {
T key;
crwwpstm::tmtype<Node*> next {nullptr};
Node() {}
Node(T key) : key{key} { }
};
alignas(128) crwwpstm::tmtype<Node*> head {nullptr};
alignas(128) crwwpstm::tmtype<Node*> tail {nullptr};
public:
CRWWPLinkedListSet(unsigned int maxThreads=0) {
Node* lhead = new Node();
Node* ltail = new Node();
head = lhead;
head->next = ltail;
tail = ltail;
}
~CRWWPLinkedListSet() {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
delete prev;
prev = node;
node = node->next;
}
delete prev;
delete tail;
}
static std::string className() { return crwwpstm::CRWWPSTM::className() + "-LinkedListSet"; }
/*
* Progress Condition: blocking
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T key, const int tid=0) {
return crwwpstm::updateTx<bool>([&] () -> bool {
Node* newNode = crwwpstm::tmNew<Node>(key);
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) break;
if (key == node->key) {
crwwpstm::tmDelete(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (node->key < key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: blocking
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T key, const int tid=0) {
return crwwpstm::updateTx<bool>([&] () -> bool {
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) return false;
if (key == node->key) {
prev->next = node->next;
crwwpstm::tmDelete(node);
return true;
}
if (node->key < key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: blocking
* Returns true if it finds a node with a matching key
*/
bool contains(T key, const int tid=0) {
return crwwpstm::readTx<bool>([&] () -> bool {
Node* node = head->next;
while (true) {
if (node == tail) return false;
if (key == node->key) return true;
if (node->key < key) return false;
node = node->next;
}
});
}
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(*keys[i], tid);
}
};
#endif /* _C_RW_WP_STM_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/linkedlists/ESTMLinkedListSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _ESTM_LINKED_LIST_SET_H_
#define _ESTM_LINKED_LIST_SET_H_
#include "../../stms/ESTM.hpp" // This header defines the macros for the STM being compiled
/**
* <h1> A Linked List Set for Elastic STM </h1>
* When we make the 'ltail' optimization here, it causes a crash on ESTM, therefore we don't do it.
*/
template<typename T>
class ESTMLinkedListSet : public estm::tmbase {
private:
struct Node : public estm::tmbase {
T key {};
estm::tmtype<Node*> next {nullptr};
Node() {}
Node(T key) : key{key} { }
};
alignas(128) estm::tmtype<Node*> head {nullptr};
alignas(128) estm::tmtype<Node*> tail {nullptr};
public:
ESTMLinkedListSet(unsigned int maxThreads=0) {
estm::updateTx([&] () {
Node* lhead = estm::tmNew<Node>();
Node* ltail = estm::tmNew<Node>();
head = lhead;
head->next = ltail;
tail = ltail;
});
}
~ESTMLinkedListSet() {
estm::updateTx([&] () {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
estm::tmDelete(prev);
prev = node;
node = node->next;
}
estm::tmDelete(prev);
estm::tmDelete(tail.load());
});
}
static std::string className() { return estm::ESTM::className() + "-LinkedListSet"; }
/*
* Progress Condition: blocking
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T key, const int tid=0) {
return estm::updateTx<bool>([this,key] () {
Node* newNode = estm::tmNew<Node>(key);
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) break;
if (key == node->key) {
estm::tmDelete(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (node->key < key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: blocking
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T key, const int tid=0) {
return estm::updateTx<bool>([this,key] () {
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) return false;
if (key == node->key) {
prev->next = node->next;
estm::tmDelete(node);
return true;
}
if (node->key < key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: blocking
* Returns true if it finds a node with a matching key
*/
bool contains(T key, const int tid=0) {
return estm::readTx<bool>([this,key] () {
Node* node = head->next;
while (true) {
if (node == tail) return false;
if (key == node->key) return true;
if (node->key < key) return false;
node = node->next;
}
});
}
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(*keys[i], tid);
return true;
}
};
#endif /* _ESTM_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/linkedlists/HazardEras.hpp
================================================
/******************************************************************************
* Copyright (c) 2016-2017, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _HAZARD_ERAS_H_
#define _HAZARD_ERAS_H_
#include <atomic>
#include <iostream>
#include <vector>
#include <algorithm>
/*
* <h1> Hazard Eras </h1>
* This a light-weight implementation of hazard eras, where each thread has a
* thread-local list of retired objects.
*
* This is based on the paper "Hazard Eras - Non-Blocking Memory Reclamation"
* by Pedro Ramalhete and Andreia Correia:
* https://github.com/pramalhe/ConcurrencyFreaks/blob/master/papers/hazarderas-2017.pdf
*
* The type T is for the objects/nodes and it's it must have the members newEra, delEra
*
* R is zero.
*
* <p>
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class HazardEras {
private:
static const uint64_t NONE = 0;
static const int HE_MAX_THREADS = 128;
static const int MAX_HES = 5; // This is named 'K' in the HP paper
static const int CLPAD = 128/sizeof(std::atomic<T*>);
static const int HE_THRESHOLD_R = 0; // This is named 'R' in the HP paper
const int maxHEs;
const int maxThreads;
alignas(128) std::atomic<uint64_t> eraClock {1};
alignas(128) std::atomic<uint64_t>* he[HE_MAX_THREADS];
// It's not nice that we have a lot of empty vectors, but we need padding to avoid false sharing
alignas(128) std::vector<T*> retiredList[HE_MAX_THREADS*CLPAD];
public:
HazardEras(int maxHEs=MAX_HES, int maxThreads=HE_MAX_THREADS) : maxHEs{maxHEs}, maxThreads{maxThreads} {
for (int it = 0; it < HE_MAX_THREADS; it++) {
he[it] = new std::atomic<uint64_t>[CLPAD*2]; // We allocate four cache lines to allow for many hps and without false sharing
retiredList[it*CLPAD].reserve(maxThreads*maxHEs);
for (int ihe = 0; ihe < MAX_HES; ihe++) {
he[it][ihe].store(NONE, std::memory_order_relaxed);
}
}
static_assert(std::is_same<decltype(T::newEra), uint64_t>::value, "T::newEra must be uint64_t");
static_assert(std::is_same<decltype(T::delEra), uint64_t>::value, "T::delEra must be uint64_t");
}
~HazardEras() {
for (int it = 0; it < HE_MAX_THREADS; it++) {
delete[] he[it];
// Clear the current retired nodes
for (unsigned iret = 0; iret < retiredList[it*CLPAD].size(); iret++) {
delete retiredList[it*CLPAD][iret];
}
}
}
inline uint64_t getEra() {
return eraClock.load();
}
/**
* Progress Condition: wait-free bounded (by maxHEs)
*/
inline void clear(const int tid) {
for (int ihe = 0; ihe < maxHEs; ihe++) {
he[tid][ihe].store(NONE, std::memory_order_release);
}
}
/**
* Progress Condition: lock-free
*/
inline T* get_protected(int index, const std::atomic<T*>& atom, const int tid) {
auto prevEra = he[tid][index].load(std::memory_order_relaxed);
while (true) {
T* ptr = atom.load();
auto era = eraClock.load(std::memory_order_acquire);
if (era == prevEra) return ptr;
he[tid][index].store(era);
prevEra = era;
}
}
inline void protectEraRelease(int index, int other, const int tid) {
auto era = he[tid][other].load(std::memory_order_relaxed);
if (he[tid][index].load(std::memory_order_relaxed) == era) return;
he[tid][index].store(era, std::memory_order_release);
}
/*
* Does a single iteration. Must be integrated into the algorithm that's using HE.
* In other words, we must re-check if era has changed
*
* Progress Condition: wait-free population oblivious
*/
inline T* protectPtr(int index, const std::atomic<T*>& atom, uint64_t& prevEra, const int tid) {
T* ptr = atom.load(std::memory_order_acquire);
auto era = eraClock.load();
if (prevEra != era) {
prevEra = era;
he[tid][index].store(era, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
return ptr;
}
/**
* Retire an object (node)
* Progress Condition: wait-free bounded
*
* Doing rlist.erase() is not the most efficient way to remove entries from a std::vector, but ok...
*/
void retire(T* ptr, const int mytid) {
auto currEra = eraClock.load();
ptr->delEra = currEra;
auto& rlist = retiredList[mytid*CLPAD];
rlist.push_back(ptr);
if (eraClock == currEra) eraClock.fetch_add(1);
for (unsigned iret = 0; iret < rlist.size();) {
auto obj = rlist[iret];
if (canDelete(obj, mytid)) {
rlist.erase(rlist.begin() + iret);
delete obj;
continue;
}
iret++;
}
}
private:
bool canDelete(T* obj, const int mytid) {
for (int tid = 0; tid < maxThreads; tid++) {
for (int ihe = 0; ihe < maxHEs; ihe++) {
const auto era = he[tid][ihe].load(std::memory_order_acquire);
if (era == NONE || era < obj->newEra || era > obj->delEra) continue;
return false;
}
}
return true;
}
};
#endif /* _HAZARD_ERAS_H_ */
================================================
FILE: datastructures/linkedlists/HazardPointers.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2017, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _HAZARD_POINTERS_H_
#define _HAZARD_POINTERS_H_
#include <atomic>
#include <iostream>
#include <vector>
template<typename T>
class HazardPointers {
private:
static const int HP_MAX_THREADS = 128;
static const int HP_MAX_HPS = 5; // This is named 'K' in the HP paper
static const int CLPAD = 128/sizeof(std::atomic<T*>);
static const int HP_THRESHOLD_R = 0; // This is named 'R' in the HP paper
static const int MAX_RETIRED = HP_MAX_THREADS*HP_MAX_HPS; // Maximum number of retired objects per thread
const int maxHPs;
const int maxThreads;
alignas(128) std::atomic<T*>* hp[HP_MAX_THREADS];
// It's not nice that we have a lot of empty vectors, but we need padding to avoid false sharing
alignas(128) std::vector<T*> retiredList[HP_MAX_THREADS*CLPAD];
public:
HazardPointers(int maxHPs=HP_MAX_HPS, int maxThreads=HP_MAX_THREADS) : maxHPs{maxHPs}, maxThreads{maxThreads} {
for (int it = 0; it < HP_MAX_THREADS; it++) {
hp[it] = new std::atomic<T*>[CLPAD*2]; // We allocate four cache lines to allow for many hps and without false sharing
retiredList[it*CLPAD].reserve(MAX_RETIRED);
for (int ihp = 0; ihp < HP_MAX_HPS; ihp++) {
hp[it][ihp].store(nullptr, std::memory_order_relaxed);
}
}
}
~HazardPointers() {
for (int it = 0; it < HP_MAX_THREADS; it++) {
delete[] hp[it];
// Clear the current retired nodes
for (unsigned iret = 0; iret < retiredList[it*CLPAD].size(); iret++) {
delete retiredList[it*CLPAD][iret];
}
}
}
/**
* Progress Condition: wait-free bounded (by maxHPs)
*/
inline void clear(const int tid) {
for (int ihp = 0; ihp < maxHPs; ihp++) {
hp[tid][ihp].store(nullptr, std::memory_order_release);
}
}
/**
* Progress Condition: wait-free population oblivious
*/
inline void clearOne(int ihp, const int tid) {
hp[tid][ihp].store(nullptr, std::memory_order_release);
}
/**
* Progress Condition: lock-free
*/
inline T* protect(int index, const std::atomic<T*>& atom, const int tid) {
T* n = nullptr;
T* ret;
while ((ret = atom.load()) != n) {
hp[tid][index].store(ret);
n = ret;
}
return ret;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free population oblivious
*/
inline T* protectPtr(int index, T* ptr, const int tid) {
hp[tid][index].store(ptr);
/*
// For x86-only implementations, use this instead (it's 2x faster than mfence on x86):
hp[tid][index].store(ptr, std::memory_order_release);
__asm__ __volatile__ ("lock;addl $0,(%%rsp);" ::: "cc","memory") ;
*/
return ptr;
}
/**
* This returns the same value that is passed as ptr, which is sometimes useful
* Progress Condition: wait-free population oblivious
*/
inline T* protectPtrRelease(int index, T* ptr, const int tid) {
hp[tid][index].store(ptr, std::memory_order_release);
return ptr;
}
/**
* Progress Condition: wait-free bounded (by the number of threads squared)
*/
void retire(T* ptr, const int tid) {
retiredList[tid*CLPAD].push_back(ptr);
if (retiredList[tid*CLPAD].size() < HP_THRESHOLD_R) return;
for (unsigned iret = 0; iret < retiredList[tid*CLPAD].size();) {
auto obj = retiredList[tid*CLPAD][iret];
bool canDelete = true;
for (int tid = 0; tid < maxThreads && canDelete; tid++) {
for (int ihp = 0; ihp < maxHPs; ihp++) {
if (hp[tid][ihp].load() == obj) {
canDelete = false;
break;
}
}
}
if (canDelete) {
retiredList[tid*CLPAD].erase(retiredList[tid*CLPAD].begin() + iret);
delete obj;
continue;
}
iret++;
}
}
};
#endif /* _HAZARD_POINTERS_H_ */
================================================
FILE: datastructures/linkedlists/MagedHarrisLinkedListSetHE.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _MAGED_M_MICHAEL_LINKED_LIST_HE_H_
#define _MAGED_M_MICHAEL_LINKED_LIST_HE_H_
#include <atomic>
#include <thread>
#include <forward_list>
#include <set>
#include <iostream>
#include <string>
#include "common/HazardEras.hpp"
/**
* This is the linked list by Maged M. Michael that uses Hazard Eras.
* Lock-Free Linked List as described in Maged M. Michael paper (Figure 7):
* http://www.cs.tau.ac.il/~afek/p73-Lock-Free-HashTbls-michael.pdf
*
* <p>
* This set has three operations:
* <ul>
* <li>add(x) - Lock-Free
* <li>remove(x) - Lock-Free
* <li>contains(x) - Lock-Free
* </ul><p>
* <p>
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class MagedHarrisLinkedListSetHE {
private:
struct Node {
T key;
uint64_t newEra;
uint64_t delEra;
std::atomic<Node*> next;
Node(T key, uint64_t newEra) : key{key}, newEra{newEra}, delEra{0}, next{nullptr} { }
bool casNext(Node *cmp, Node *val) {
return next.compare_exchange_strong(cmp, val);
}
};
// Pointers to head and tail sentinel nodes of the list
std::atomic<Node*> head;
std::atomic<Node*> tail;
const int maxThreads;
HazardEras<Node> he {3, maxThreads};
const int kHp0 = 0; // Protects next
const int kHp1 = 1; // Protects curr
const int kHp2 = 2; // Protects prev
public:
MagedHarrisLinkedListSetHE(const int maxThreads) : maxThreads{maxThreads} {
head.store(new Node({}, 1)); // Uses K's default constructor
tail.store(new Node({}, 1)); // Uses K's default constructor
head.load()->next.store(tail.load());
}
// We don't expect the destructor to be called if this instance can still be in use
~MagedHarrisLinkedListSetHE() {
Node *prev = head.load();
Node *node = prev->next.load();
while (node != nullptr) {
delete prev;
prev = node;
node = prev->next.load();
}
delete prev;
}
static std::string className() { return "MagedHarris-LinkedListSetHE"; }
/*
* This function is single threaded to be called at the start of the test.
* It is assumed keys are ordered
*/
void addAll(T** keys, const int size, const int tid) {
Node* node = head;
for(int i=0;i<size;i++){
T* key = keys[i];
Node* newNode = new Node(*key, 1);
node->next.store(newNode, std::memory_order_relaxed);
node = newNode;
}
node->next.store(tail.load(std::memory_order_relaxed), std::memory_order_relaxed);
}
/**
* This method is named 'Insert()' in the original paper.
* Taken from Figure 7 of the paper:
* "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
* <p>
* Progress Condition: Lock-Free
*
*/
bool add(T key, const int tid)
{
Node *curr, *next;
std::atomic<Node*> *prev;
Node* newNode = new Node(key, he.getEra());
while (true) {
if (find(&key, &prev, &curr, &next, tid)) {
delete newNode; // There is already a matching key
he.clear(tid);
return false;
}
newNode->next.store(curr, std::memory_order_relaxed);
Node *tmp = getUnmarked(curr);
if (prev->compare_exchange_strong(tmp, newNode)) { // seq-cst
he.clear(tid);
return true;
}
}
}
/**
* This method is named 'Delete()' in the original paper.
* Taken from Figure 7 of the paper:
* "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
*/
bool remove(T key, const int tid)
{
Node *curr, *next;
std::atomic<Node*> *prev;
while (true) {
/* Try to find the key in the list. */
if (!find(&key, &prev, &curr, &next, tid)) {
he.clear(tid);
return false;
}
/* Mark if needed. */
Node *tmp = getUnmarked(next);
if (!curr->next.compare_exchange_strong(tmp, getMarked(next))) {
continue; /* Another thread interfered. */
}
tmp = getUnmarked(curr);
if (prev->compare_exchange_strong(tmp, getUnmarked(next))) { /* Unlink */
he.clear(tid);
he.retire(getUnmarked(curr), tid); /* Reclaim */
} else {
he.clear(tid);
}
/*
* If we want to prevent the possibility of there being an
* unbounded number of unmarked nodes, add "else _find(head,key)."
* This is not necessary for correctness.
*/
return true;
}
}
/**
* This is named 'Search()' on the original paper
* Taken from Figure 7 of the paper:
* "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
* <p>
* Progress Condition: Lock-Free
*/
bool contains(T key, const int tid)
{
Node *curr, *next;
std::atomic<Node*> *prev;
bool isContains = find(&key, &prev, &curr, &next, tid);
he.clear(tid);
return isContains;
}
private:
/**
* <p>
* Progress Condition: Lock-Free
*/
bool find (T* key, std::atomic<Node*> **par_prev, Node **par_curr, Node **par_next, const int tid)
{
std::atomic<Node*> *prev;
Node *curr, *next;
try_again:
prev = &head;
// Protect curr with a hazard era
curr = he.get_protected(kHp1, *prev, tid);
while (true) {
if (getUnmarked(curr) == nullptr) break; // TODO: Will it ever happen?
// Protect next with a hazard era.
next = he.get_protected(kHp0, curr->next, tid);
if (getUnmarked(curr)->next.load() != next) goto try_again;
if (getUnmarked(next) == tail.load()) break;
if (prev->load() != getUnmarked(curr)) goto try_again;
if (getUnmarked(next) == next) { // !cmark in the paper
if (!(getUnmarked(curr)->key < *key)) { // Check for null to handle head and tail
*par_curr = curr;
*par_prev = prev;
*par_next = next;
return (getUnmarked(curr)->key == *key);
}
prev = &getUnmarked(curr)->next;
he.protectEraRelease(kHp2, kHp1, tid);
} else {
// Update the link and retire the node.
Node *tmp = getUnmarked(curr);
if (!prev->compare_exchange_strong(tmp, getUnmarked(next))) {
goto try_again;
}
he.retire(getUnmarked(curr), tid);
}
curr = next;
he.protectEraRelease(kHp1, kHp0, tid);
}
*par_curr = curr;
*par_prev = prev;
*par_next = next;
return false;
}
bool isMarked(Node * node) {
return ((size_t) node & 0x1);
}
Node * getMarked(Node * node) {
return (Node*)((size_t) node | 0x1);
}
Node * getUnmarked(Node * node) {
return (Node*)((size_t) node & (~0x1));
}
};
#endif /* _MAGED_M_MICHAEL_LINKED_LIST_HE_H_ */
================================================
FILE: datastructures/linkedlists/MagedHarrisLinkedListSetHP.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2016, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _MAGED_MICHAEL_TIM_HARRIS_LINKED_LIST_HP_H_
#define _MAGED_MICHAEL_TIM_HARRIS_LINKED_LIST_HP_H_
#include <atomic>
#include <thread>
#include <forward_list>
#include <set>
#include <iostream>
#include <string>
#include "common/HazardPointers.hpp"
/**
* This is the linked list by Maged M. Michael that uses Hazard Pointers in
* a correct way because Harris original algorithm with HPs doesn't.
* Lock-Free Linked List as described in Maged M. Michael paper (Figure 4):
* http://www.cs.tau.ac.il/~afek/p73-Lock-Free-HashTbls-michael.pdf
*
*
* <p>
* This set has three operations:
* <ul>
* <li>add(x) - Lock-Free
* <li>remove(x) - Lock-Free
* <li>contains(x) - Lock-Free
* </ul><p>
* <p>
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class MagedHarrisLinkedListSetHP {
private:
struct Node {
T key;
std::atomic<Node*> next;
Node(T key) : key{key}, next{nullptr} { }
bool casNext(Node *cmp, Node *val) {
return next.compare_exchange_strong(cmp, val);
}
};
// Pointers to head and tail sentinel nodes of the list
std::atomic<Node*> head;
std::atomic<Node*> tail;
const int maxThreads;
// We need 3 hazard pointers
HazardPointers<Node> hp {3, maxThreads};
const int kHp0 = 0; // Protects next
const int kHp1 = 1; // Protects curr
const int kHp2 = 2; // Protects prev
public:
MagedHarrisLinkedListSetHP(const int maxThreads) : maxThreads{maxThreads} {
head.store(new Node({}));
tail.store(new Node({}));
head.load()->next.store(tail.load());
}
// We don't expect the destructor to be called if this instance can still be in use
~MagedHarrisLinkedListSetHP() {
Node *prev = head.load();
Node *node = prev->next.load();
while (node != nullptr) {
delete prev;
prev = node;
node = prev->next.load();
}
delete prev;
}
static std::string className() { return "MagedHarris-LinkedListSetHP"; }
/*
* This function is single threaded to be called at the start of the test.
* It is assumed keys are ordered
*/
void addAll(T** keys, const int size, const int tid) {
Node* node = head;
for(int i=0;i<size;i++){
T* key = keys[i];
Node* newNode = new Node(*key);
node->next.store(newNode, std::memory_order_relaxed);
node = newNode;
}
node->next.store(tail.load(std::memory_order_relaxed), std::memory_order_relaxed);
}
/**
* This method is named 'Insert()' in the original paper.
* Taken from Figure 7 of the paper:
* "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
* <p>
* Progress Condition: Lock-Free
*
*/
bool add(T key, const int tid)
{
Node *curr, *next;
std::atomic<Node*> *prev;
Node* newNode = new Node(key);
while (true) {
if (find(&key, &prev, &curr, &next, tid)) {
delete newNode; // There is already a matching key
hp.clear(tid);
return false;
}
newNode->next.store(curr, std::memory_order_relaxed);
Node *tmp = getUnmarked(curr);
if (prev->compare_exchange_strong(tmp, newNode)) { // seq-cst
hp.clear(tid);
return true;
}
}
}
/**
* This method is named 'Delete()' in the original paper.
* Taken from Figure 7 of the paper:
* "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
*/
bool remove(T key, const int tid)
{
Node *curr, *next;
std::atomic<Node*> *prev;
while (true) {
/* Try to find the key in the list. */
if (!find(&key, &prev, &curr, &next, tid)) {
hp.clear(tid);
return false;
}
/* Mark if needed. */
Node *tmp = getUnmarked(next);
if (!curr->next.compare_exchange_strong(tmp, getMarked(next))) {
continue; /* Another thread interfered. */
}
tmp = getUnmarked(curr);
if (prev->compare_exchange_strong(tmp, getUnmarked(next))) { /* Unlink */
hp.clear(tid);
hp.retire(getUnmarked(curr), tid); /* Reclaim */
} else {
hp.clear(tid);
}
/*
* If we want to prevent the possibility of there being an
* unbounded number of unmarked nodes, add "else _find(head,key)."
* This is not necessary for correctness.
*/
return true;
}
}
/**
* This is named 'Search()' on the original paper
* Taken from Figure 7 of the paper:
* "High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
* <p>
* Progress Condition: Lock-Free
*/
bool contains(T key, const int tid)
{
Node *curr, *next;
std::atomic<Node*> *prev;
bool isContains = find(&key, &prev, &curr, &next, tid);
hp.clear(tid);
return isContains;
}
private:
/**
* TODO: This needs to be code reviewed... it's not production-ready
* <p>
* Progress Condition: Lock-Free
*/
bool find (T* key, std::atomic<Node*> **par_prev, Node **par_curr, Node **par_next, const int tid)
{
std::atomic<Node*> *prev;
Node *curr, *next;
try_again:
prev = &head;
curr = prev->load();
// Protect curr with a hazard pointer.
hp.protectPtr(kHp1, curr, tid);
if (prev->load() != getUnmarked(curr)) goto try_again;
while (true) {
if (getUnmarked(curr) == nullptr) break;
// Protect next with a hazard pointer.
next = curr->next.load();
hp.protectPtr(kHp0, getUnmarked(next), tid);
if (getUnmarked(curr)->next.load() != next) goto try_again;
if (getUnmarked(next) == tail.load()) break;
if (prev->load() != getUnmarked(curr)) goto try_again;
if (getUnmarked(next) == next) { // !cmark in the paper
if (!(getUnmarked(curr)->key < *key)) { // Check for null to handle head and tail
*par_curr = curr;
*par_prev = prev;
*par_next = next;
return (getUnmarked(curr)->key == *key);
}
prev = &getUnmarked(curr)->next;
hp.protectRelease(kHp2, getUnmarked(curr), tid);
} else {
// Update the link and retire the node.
Node *tmp = getUnmarked(curr);
if (!prev->compare_exchange_strong(tmp, getUnmarked(next))) {
goto try_again;
}
hp.retire(getUnmarked(curr), tid);
}
curr = next;
hp.protectRelease(kHp1, getUnmarked(next), tid);
}
*par_curr = curr;
*par_prev = prev;
*par_next = next;
return false;
}
bool isMarked(Node * node) {
return ((size_t) node & 0x1);
}
Node * getMarked(Node * node) {
return (Node*)((size_t) node | 0x1);
}
Node * getUnmarked(Node * node) {
return (Node*)((size_t) node & (~0x1));
}
};
#endif /* _MAGED_MICHAEL_TIM_HARRIS_LINKED_LIST_HP_H_ */
================================================
FILE: datastructures/linkedlists/OFLFLinkedListSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _ONEFILE_LF_LINKED_LIST_SET_H_
#define _ONEFILE_LF_LINKED_LIST_SET_H_
#include <atomic>
#include <stdexcept>
#include "stms/OneFileLF.hpp"
/**
* <h1> A Linked List Set for One-File STM (Lock-Free) </h1>
*/
template<typename T>
class OFLFLinkedListSet : public oflf::tmbase {
private:
struct Node : public oflf::tmbase {
T key {};
oflf::tmtype<Node*> next {nullptr};
Node() {}
Node(T key) : key{key} { }
};
alignas(128) oflf::tmtype<Node*> head {nullptr};
alignas(128) oflf::tmtype<Node*> tail {nullptr};
public:
OFLFLinkedListSet(unsigned int maxThreads=0) {
oflf::updateTx([this] () {
Node* lhead = oflf::tmNew<Node>();
Node* ltail = oflf::tmNew<Node>();
head = lhead;
head->next = ltail;
tail = ltail;
});
}
~OFLFLinkedListSet() {
oflf::updateTx([this] () {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
oflf::tmDelete(prev);
prev = node;
node = node->next;
}
oflf::tmDelete(prev);
oflf::tmDelete(tail.pload());
});
}
static std::string className() { return oflf::OneFileLF::className() + "-LinkedListSet"; }
/*
* Progress Condition: lock-free
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T key, const int tid=0) {
return oflf::updateTx<bool>([this,key] () -> bool {
Node* newNode = oflf::tmNew<Node>(key);
Node* prev = head;
Node* node = prev->next;
Node* ltail = tail;
while (true) {
if (node == ltail) break;
T nkey = node->key;
if (key == nkey) {
oflf::tmDelete(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (nkey < key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: lock-free
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T key, const int tid=0) {
return oflf::updateTx<bool>([this,key] () -> bool {
Node* prev = head;
Node* node = prev->next;
Node* ltail = tail;
while (true) {
if (node == ltail) return false;
T nkey = node->key;
if (key == nkey) {
prev->next = node->next;
oflf::tmDelete(node);
return true;
}
if (nkey < key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: lock-free
* Returns true if it finds a node with a matching key
*/
bool contains(T key, const int tid=0) {
return oflf::readTx<bool>([this,key] () -> bool {
Node* node = head->next;
Node* ltail = tail;
while (true) {
if (node == ltail) return false;
T nkey = node->key;
if (key == nkey) return true;
if (nkey < key) return false;
node = node->next;
}
});
}
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(*keys[i], tid);
return true;
}
};
#endif /* _ONE_FILE_LF_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/linkedlists/OFWFLinkedListSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _ONEFILE_WF_LINKED_LIST_SET_H_
#define _ONEFILE_WF_LINKED_LIST_SET_H_
#include <atomic>
#include <stdexcept>
#include "stms/OneFileWF.hpp"
/**
* <h1> A Linked List Set for One-File STM (wait-Free) </h1>
*/
template<typename T>
class OFWFLinkedListSet : public ofwf::tmbase {
private:
struct Node : public ofwf::tmbase {
T key {};
ofwf::tmtype<Node*> next {nullptr};
Node(T key) : key{key} { }
Node() {}
};
alignas(128) ofwf::tmtype<Node*> head {nullptr};
alignas(128) ofwf::tmtype<Node*> tail {nullptr};
public:
OFWFLinkedListSet(unsigned int maxThreads=0) {
ofwf::updateTx([this] () {
Node* lhead = ofwf::tmNew<Node>();
Node* ltail = ofwf::tmNew<Node>();
head = lhead;
head->next = ltail;
tail = ltail;
});
}
~OFWFLinkedListSet() {
ofwf::updateTx([this] () {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
ofwf::tmDelete(prev);
prev = node;
node = node->next;
}
ofwf::tmDelete(prev);
ofwf::tmDelete(tail.pload());
});
}
static std::string className() { return ofwf::OneFileWF::className() + "-LinkedListSet"; }
/*
* Progress Condition: wait-free
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T key, const int tid=0) {
return ofwf::updateTx<bool>([this,key] () {
Node* newNode = ofwf::tmNew<Node>(key);
Node* prev = head;
Node* node = prev->next;
Node* ltail = tail;
while (true) {
if (node == ltail) break;
T nkey = node->key;
if (key == nkey) {
ofwf::tmDelete(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (nkey < key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: wait-free
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T key, const int tid=0) {
return ofwf::updateTx<bool>([this,key] () {
Node* prev = head;
Node* node = prev->next;
Node* ltail = tail;
while (true) {
if (node == ltail) return false;
T nkey = node->key;
if (key == nkey) {
prev->next = node->next;
ofwf::tmDelete(node);
return true;
}
if (nkey < key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: wait-free
* Returns true if it finds a node with a matching key
*/
bool contains(T key, const int tid=0) {
return ofwf::readTx<bool>([this,key] () {
Node* node = head->next;
Node* ltail = tail;
while (true) {
if (node == ltail) return false;
T nkey = node->key;
if (key == nkey) return true;
if (nkey < key) return false;
node = node->next;
}
});
}
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(*keys[i], tid);
return true;
}
};
#endif /* _ONE_FILE_WF_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/linkedlists/STMLinkedListSet.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2018, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _STM_LINKED_LIST_SET_H_
#define _STM_LINKED_LIST_SET_H_
#include <atomic>
#include <stdexcept>
//#include "stms/OneFileLF.hpp"
/**
* <h1> A Linked List Set for an STM </h1>
*
* TODO
*
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T, typename TM, template<typename> class TMTYPE, template<typename> class TMBASE>
class STMLinkedListSet : public TMBASE {
private:
struct Node : public TMBASE {
T* key;
TMTYPE<Node*> next;
Node(T* key) : key{key}, next{nullptr} { }
};
alignas(128) TMTYPE<Node*> head {nullptr};
alignas(128) TMTYPE<Node*> tail {nullptr};
public:
STMLinkedListSet(unsigned int maxThreads=0) {
Node* lhead = new Node(nullptr);
Node* ltail = new Node(nullptr);
head = lhead;
head->next = ltail;
tail = ltail;
}
~STMLinkedListSet() {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
delete prev;
prev = node;
node = node->next;
}
delete prev;
delete tail;
}
static std::string className() { return TM::className() + "-LinkedListSet"; }
/*
* Progress Condition: lock-free
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T* key, const int tid=0) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
return TM::updateTx<bool>([this,key] () -> bool {
Node* newNode = TM::tmNew<Node>(key);
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) break;
if (*key == *node->key) {
TM::tmDelete(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (*(node->key) < *key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: lock-free
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T* key, const int tid=0) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
return TM::updateTx<bool>([this,key] () -> bool {
Node* prev = head;
Node* node = prev->next;
while (true) {
if (node == tail) return false;
if (*key == *node->key) {
prev->next = node->next;
TM::tmDelete(node);
return true;
}
if (*(node->key) < *key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: lock-free
* Returns true if it finds a node with a matching key
*/
bool contains(T* key, const int tid=0) {
if (key == nullptr) throw std::invalid_argument("key can not be nullptr");
return TM::readTx<bool>([this,key] () -> bool {
Node* node = head->next;
while (true) {
if (node == tail) return false;
if (*key == *node->key) return true;
if (*(node->key) < *key) return false;
node = node->next;
}
});
}
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(keys[i], tid);
}
};
#endif /* _ONE_FILE_LF_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/linkedlists/TinySTMLinkedListSet.hpp
================================================
/*
* Copyright 2017-2018
* Andreia Correia <andreia.veiga@unine.ch>
* Pedro Ramalhete <pramalhe@gmail.com>
* Pascal Felber <pascal.felber@unine.ch>
* Nachshon Cohen <nachshonc@gmail.com>
*
* This work is published under the MIT license. See LICENSE.txt
*/
#ifndef _TINY_STM_LINKED_LIST_SET_H_
#define _TINY_STM_LINKED_LIST_SET_H_
#include "stms/TinySTM.hpp"
/**
* <h1> A Linked List Set for usage with TinySTM </h1>
*/
template<typename T>
class TinySTMLinkedListSet : public tinystm::tmbase {
private:
struct Node : public tinystm::tmbase {
T key;
tinystm::tmtype<Node*> next{nullptr};
Node() {}
Node(T key) : key{key} { }
};
alignas(128) tinystm::tmtype<Node*> head {nullptr};
alignas(128) tinystm::tmtype<Node*> tail {nullptr};
public:
TinySTMLinkedListSet(unsigned int maxThreads=0) {
tinystm::updateTx<bool>([this] () {
Node* lhead = tinystm::tmNew<Node>();
Node* ltail = tinystm::tmNew<Node>();
head = lhead;
head->next = ltail;
tail = ltail;
return true;
});
}
~TinySTMLinkedListSet() {
tinystm::updateTx<bool>([this] () {
// Delete all the nodes in the list
Node* prev = head;
Node* node = prev->next;
while (node != tail) {
tinystm::tmDelete(prev);
prev = node;
node = node->next;
}
tinystm::tmDelete(prev);
tinystm::tmDelete(tail.load());
return true;
});
}
static std::string className() { return "TinySTM-LinkedListSet"; }
/*
* Progress Condition: blocking
* Adds a node with a key, returns false if the key is already in the set
*/
bool add(T key, const int tid=0) {
return tinystm::updateTx<bool>([this,key] () {
Node* newNode = tinystm::tmNew<Node>(key);
Node* prev = head;
Node* node = prev->next;
Node* ltail = tail;
while (true) {
if (node == ltail) break;
T nkey = node->key;
if (key == nkey) {
tinystm::tmDelete(newNode); // If the key was already in the set, free the node that was never used
return false;
}
if (nkey < key) break;
prev = node;
node = node->next;
}
prev->next = newNode;
newNode->next = node;
return true;
});
}
/*
* Progress Condition: blocking
* Removes a node with an key, returns false if the key is not in the set
*/
bool remove(T key, const int tid=0) {
return tinystm::updateTx<bool>([this,key] () {
Node* prev = head;
Node* node = prev->next;
Node* ltail = tail;
while (true) {
if (node == ltail) return false;
T nkey = node->key;
if (key == nkey) {
prev->next = node->next;
tinystm::tmDelete(node);
return true;
}
if (nkey < key) return false;
prev = node;
node = node->next;
}
});
}
/*
* Progress Condition: blocking
* Returns true if it finds a node with a matching key
*/
bool contains(T key, const int tid=0) {
return tinystm::readTx<bool>([this,key] () {
Node* node = head->next;
Node* ltail = tail;
while (true) {
if (node == ltail) return false;
T nkey = node->key;
if (key == nkey) return true;
if (nkey < key) return false;
node = node->next;
}
});
}
bool addAll(T** keys, int size, const int tid) {
for (int i = 0; i < size; i++) add(*keys[i], tid);
}
};
#endif /* _TINY_STM_LINKED_LIST_SET_H_ */
================================================
FILE: datastructures/queues/CRWWPLinkedListQueue.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2017, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _CRWWP_LINKED_LIST_QUEUE_H_
#define _CRWWP_LINKED_LIST_QUEUE_H_
#include <atomic>
#include <stdexcept>
#include "../../stms/CRWWPSTM.hpp"
/**
* <h1> A Linked List queue using C-RW-WP STM </h1>
*
*
* TODO
*
*
* enqueue algorithm: sequential implementation + MWC
* dequeue algorithm: sequential implementation + MWC
* Consistency: Linearizable
* enqueue() progress: lock-free
* dequeue() progress: lock-free
* Memory Reclamation: Hazard Eras (integrated into MWC)
* enqueue min ops: 2 DCAS + 1 CAS
* dequeue min ops: 1 DCAS + 1 CAS
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class CRWWPLinkedListQueue {
private:
struct Node : crwwpstm::tmbase {
T* item;
crwwpstm::tmtype<Node*> next;
Node(T* userItem) : item{userItem}, next{nullptr} { }
};
alignas(128) crwwpstm::tmtype<Node*> head {nullptr};
alignas(128) crwwpstm::tmtype<Node*> tail {nullptr};
public:
CRWWPLinkedListQueue(unsigned int maxThreads=0) {
Node* sentinelNode = new Node(nullptr);
head = sentinelNode;
tail = sentinelNode;
}
~CRWWPLinkedListQueue() {
while (dequeue() != nullptr); // Drain the queue
Node* lhead = head;
delete lhead;
}
static std::string className() { return "CRWWP-LinkedListQueue"; }
/*
* Progress Condition: lock-free
* Always returns true
*/
bool enqueue(T* item, const int tid=0) {
if (item == nullptr) throw std::invalid_argument("item can not be nullptr");
Node* newNode = crwwpstm::tmNew<Node>(item); // Let's allocate outside the transaction, less overhead
return crwwpstm::updateTx<bool>([this,&newNode] () -> bool {
tail->next = newNode;
tail = newNode;
return true;
});
}
/*
* Progress Condition: lock-free
*/
T* dequeue(const int tid=0) {
return crwwpstm::updateTx<T*>([this] () -> T* {
Node* lhead = head;
if (lhead == tail) return nullptr;
head = lhead->next;
crwwpstm::tmDelete(lhead);
return head->item;
});
}
};
#endif /* _CRWWP_TM_LINKED_LIST_QUEUE_H_ */
================================================
FILE: datastructures/queues/ESTMArrayLinkedListQueue.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2017, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _ELASTIC_STM_ARRAY_LINKED_LIST_QUEUE_H_
#define _ELASTIC_STM_ARRAY_LINKED_LIST_QUEUE_H_
#include <atomic>
#include <stdexcept>
#include "stms/ESTM.hpp"
/**
* <h1> An Array Linked List Queue using OneFile STM (Wait-Free) </h1>
*
* TODO
*
*
* enqueue algorithm: sequential implementation + MWC
* dequeue algorithm: sequential implementation + MWC
* Consistency: Linearizable
* enqueue() progress: lock-free
* dequeue() progress: lock-free
* Memory Reclamation: Hazard Eras (integrated into MWC)
* enqueue min ops: 2 DCAS + 1 CAS
* dequeue min ops: 1 DCAS + 1 CAS
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class ESTMArrayLinkedListQueue {
private:
struct Node : estm::tmbase {
static const int ITEM_NUM = 1024;
estm::tmtype<uint64_t> headidx {0};
estm::tmtype<T*> items[ITEM_NUM];
estm::tmtype<uint64_t> tailidx {0};
estm::tmtype<Node*> next {nullptr};
Node(T* item) {
items[0] = item;
tailidx = 1;
headidx = 0;
for (int i = 1; i < ITEM_NUM; i++) items[i] = nullptr;
}
};
alignas(128) estm::tmtype<Node*> head {nullptr};
alignas(128) estm::tmtype<Node*> tail {nullptr};
public:
ESTMArrayLinkedListQueue(unsigned int maxThreads=0) {
estm::updateTx<bool>([this] () {
Node* sentinelNode = estm::tmNew<Node>(nullptr);
sentinelNode->tailidx = 0;
head = sentinelNode;
tail = sentinelNode;
return true;
});
}
~ESTMArrayLinkedListQueue() {
while (dequeue() != nullptr); // Drain the queue
estm::updateTx<bool>([this] () {
Node* lhead = head;
estm::tmDelete(lhead);
return true;
});
}
static std::string className() { return "ESTM-ArrayLinkedListQueue"; }
/*
* Progress Condition: blocking
* Always returns true
*/
bool enqueue(T* item, const int tid=0) {
if (item == nullptr) throw std::invalid_argument("item can not be nullptr");
return estm::updateTx<bool>([this,item] () -> bool {
Node* ltail = tail;
uint64_t ltailidx = ltail->tailidx;
if (ltailidx < Node::ITEM_NUM) {
ltail->items[ltailidx] = item;
++ltail->tailidx;
return true;
}
Node* newNode = estm::tmNew<Node>(item);
tail->next = newNode;
tail = newNode;
return true;
});
}
/*
* Progress Condition: blocking
*/
T* dequeue(const int tid=0) {
return estm::updateTx<T*>([this] () -> T* {
Node* lhead = head;
uint64_t lheadidx = lhead->headidx;
// Check if queue is empty
if (lhead == tail && lheadidx == tail->tailidx) return nullptr;
if (lheadidx < Node::ITEM_NUM) {
++lhead->headidx;
return lhead->items[lheadidx];
}
lhead = lhead->next;
estm::tmDelete(head.load());
head = lhead;
++lhead->headidx;
return lhead->items[0];
});
}
};
#endif /* _OF_WF_ARRAY_LINKED_LIST_QUEUE_H_ */
================================================
FILE: datastructures/queues/ESTMLinkedListQueue.hpp
================================================
/******************************************************************************
* Copyright (c) 2014-2018, Pedro Ramalhete, Andreia Correia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Concurrency Freaks nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************
*/
#ifndef _ELASTIC_STM_LINKED_LIST_QUEUE_H_
#define _ELASTIC_STM_LINKED_LIST_QUEUE_H_
#include <atomic>
#include <stdexcept>
#include "stms/ESTM.hpp"
/**
* <h1> A Linked List queue using Elastic STM (blocking) </h1>
*
*
* TODO
*
* @author Pedro Ramalhete
* @author Andreia Correia
*/
template<typename T>
class ESTMLinkedListQueue {
private:
struct Node : estm::tmbase {
T* item;
estm::tmtype<Node*> next {nullptr};
Node(T* userItem) : item{userItem} { }
};
alignas(128) estm::tmtype<Node*> head {nullptr};
alignas(128) estm::tmtype<Node*> tail {nullptr};
public:
ESTMLinkedListQueue(unsigned int maxThreads=0) {
estm::updateTx<bool>([this] () {
Node* sentinelNode = estm::tmNew<Node>(nullptr);
head = sentinelNode;
tail = sentinelNode;
return true;
});
}
~ESTMLinkedListQueue() {
while (dequeue() != nullptr); // Drain the queue
estm::updateTx<bool>([this] () {
Node* lhead = head;
estm::tmDelete(lhead);
return true;
});
}
static std::string className() { return "ESTM-LinkedListQueue"; }
/*
* Progress Condition: blocking
* Always returns true
*/
bool enqueue(T* item, const int tid=0) {
if (item == nullptr) throw std::invalid_argument("item can not be nullptr");
return estm::updateTx<bool>([this,item] () -> bool {
Node* newNode = estm::tmNew<Node>(item);
tail->next = newNode;
tail = newNode;
return true;
});
}
/*
* Progress Condition: blocking
*/
T* dequeue(const int tid=0) {
return estm::updateTx<T*>([this] () -> T* {
Node* lhead = head;
if (lhead == tail) return nullptr;
head = lhead->next;
estm::tmDelete(lhead);
return head->item;
});
}
};
#endif /* _ESTM_LINKED_LIST_
gitextract_33ubg_0h/
├── LICENSE.txt
├── README.md
├── common/
│ ├── HazardEras.hpp
│ ├── HazardPointers.hpp
│ ├── HazardPointersSimQueue.hpp
│ ├── README.md
│ ├── RIStaticPerThread.hpp
│ ├── ThreadRegistry.cpp
│ ├── ThreadRegistry.hpp
│ └── pfences.h
├── datastructures/
│ ├── generic/
│ │ ├── TMHashMap.hpp
│ │ ├── TMLinkedListQueue.hpp
│ │ ├── TMLinkedListSet.hpp
│ │ └── TMRedBlackBST.hpp
│ ├── hashmaps/
│ │ ├── CRWWPSTMResizableHashSet.hpp
│ │ ├── ESTMResizableHashSet.hpp
│ │ ├── OFLFResizableHashSet.hpp
│ │ ├── OFWFResizableHashSet.hpp
│ │ └── TinySTMResizableHashSet.hpp
│ ├── linkedlists/
│ │ ├── CRWWPLinkedListSet.hpp
│ │ ├── ESTMLinkedListSet.hpp
│ │ ├── HazardEras.hpp
│ │ ├── HazardPointers.hpp
│ │ ├── MagedHarrisLinkedListSetHE.hpp
│ │ ├── MagedHarrisLinkedListSetHP.hpp
│ │ ├── OFLFLinkedListSet.hpp
│ │ ├── OFWFLinkedListSet.hpp
│ │ ├── STMLinkedListSet.hpp
│ │ └── TinySTMLinkedListSet.hpp
│ ├── queues/
│ │ ├── CRWWPLinkedListQueue.hpp
│ │ ├── ESTMArrayLinkedListQueue.hpp
│ │ ├── ESTMLinkedListQueue.hpp
│ │ ├── FAAArrayQueue.hpp
│ │ ├── HazardPointers.hpp
│ │ ├── HazardPointersSimQueue.hpp
│ │ ├── LCRQueue.hpp
│ │ ├── MichaelScottQueue.hpp
│ │ ├── OFLFArrayLinkedListQueue.hpp
│ │ ├── OFLFArrayQueue.hpp
│ │ ├── OFLFLinkedListQueue.hpp
│ │ ├── OFWFArrayLinkedListQueue.hpp
│ │ ├── OFWFLinkedListQueue.hpp
│ │ ├── README.md
│ │ ├── SimQueue.hpp
│ │ ├── TinySTMArrayLinkedListQueue.hpp
│ │ ├── TinySTMLinkedListQueue.hpp
│ │ └── TurnQueue.hpp
│ ├── sequential/
│ │ ├── HashSet.hpp
│ │ ├── LinkedListQueue.hpp
│ │ ├── LinkedListSet.hpp
│ │ ├── RedBlackBST.hpp
│ │ ├── SortedArraySet.hpp
│ │ ├── SortedVectorSet.hpp
│ │ └── TreeSet.hpp
│ ├── treemaps/
│ │ ├── ESTMRedBlackTree.hpp
│ │ ├── HazardEras.hpp
│ │ ├── NatarajanTreeHE.hpp
│ │ ├── OFLFRedBlackTree.hpp
│ │ ├── OFWFRedBlackTree.hpp
│ │ └── TinySTMRedBlackTree.hpp
│ ├── trevor_brown_abtree/
│ │ ├── Makefile
│ │ ├── TrevorBrownABTree.hpp
│ │ ├── common/
│ │ │ ├── atomic_ops/
│ │ │ │ ├── atomic_ops/
│ │ │ │ │ ├── generalize-small.h
│ │ │ │ │ ├── generalize.h
│ │ │ │ │ └── sysdeps/
│ │ │ │ │ ├── README
│ │ │ │ │ ├── acquire_release_volatile.h
│ │ │ │ │ ├── aligned_atomic_load_store.h
│ │ │ │ │ ├── all_acquire_release_volatile.h
│ │ │ │ │ ├── all_aligned_atomic_load_store.h
│ │ │ │ │ ├── all_atomic_load_store.h
│ │ │ │ │ ├── ao_t_is_int.h
│ │ │ │ │ ├── armcc/
│ │ │ │ │ │ └── arm_v6.h
│ │ │ │ │ ├── atomic_load_store.h
│ │ │ │ │ ├── char_acquire_release_volatile.h
│ │ │ │ │ ├── char_atomic_load_store.h
│ │ │ │ │ ├── emul_cas.h
│ │ │ │ │ ├── gcc/
│ │ │ │ │ │ ├── alpha.h
│ │ │ │ │ │ ├── arm.h
│ │ │ │ │ │ ├── avr32.h
│ │ │ │ │ │ ├── cris.h
│ │ │ │ │ │ ├── hppa.h
│ │ │ │ │ │ ├── ia64.h
│ │ │ │ │ │ ├── m68k.h
│ │ │ │ │ │ ├── mips.h
│ │ │ │ │ │ ├── powerpc.h
│ │ │ │ │ │ ├── s390.h
│ │ │ │ │ │ ├── sh.h
│ │ │ │ │ │ ├── sparc.h
│ │ │ │ │ │ ├── x86.h
│ │ │ │ │ │ └── x86_64.h
│ │ │ │ │ ├── generic_pthread.h
│ │ │ │ │ ├── hpc/
│ │ │ │ │ │ ├── hppa.h
│ │ │ │ │ │ └── ia64.h
│ │ │ │ │ ├── ibmc/
│ │ │ │ │ │ └── powerpc.h
│ │ │ │ │ ├── icc/
│ │ │ │ │ │ └── ia64.h
│ │ │ │ │ ├── int_acquire_release_volatile.h
│ │ │ │ │ ├── int_aligned_atomic_load_store.h
│ │ │ │ │ ├── int_atomic_load_store.h
│ │ │ │ │ ├── msftc/
│ │ │ │ │ │ ├── arm.h
│ │ │ │ │ │ ├── common32_defs.h
│ │ │ │ │ │ ├── x86.h
│ │ │ │ │ │ └── x86_64.h
│ │ │ │ │ ├── ordered.h
│ │ │ │ │ ├── ordered_except_wr.h
│ │ │ │ │ ├── read_ordered.h
│ │ │ │ │ ├── short_acquire_release_volatile.h
│ │ │ │ │ ├── short_aligned_atomic_load_store.h
│ │ │ │ │ ├── short_atomic_load_store.h
│ │ │ │ │ ├── standard_ao_double_t.h
│ │ │ │ │ ├── sunc/
│ │ │ │ │ │ ├── sparc.h
│ │ │ │ │ │ ├── x86.h
│ │ │ │ │ │ └── x86_64.h
│ │ │ │ │ ├── test_and_set_t_is_ao_t.h
│ │ │ │ │ └── test_and_set_t_is_char.h
│ │ │ │ └── atomic_ops.h
│ │ │ ├── dcss/
│ │ │ │ ├── dcss_plus.h
│ │ │ │ ├── dcss_plus_impl.h
│ │ │ │ └── testing.cpp
│ │ │ ├── descriptors/
│ │ │ │ ├── descriptors.h
│ │ │ │ ├── descriptors_impl.h
│ │ │ │ └── descriptors_impl2.h
│ │ │ ├── errors.h
│ │ │ ├── plaf.h
│ │ │ ├── recordmgr/
│ │ │ │ ├── allocator_bump.h
│ │ │ │ ├── allocator_interface.h
│ │ │ │ ├── allocator_new.h
│ │ │ │ ├── allocator_new_segregated.h
│ │ │ │ ├── allocator_once.h
│ │ │ │ ├── arraylist.h
│ │ │ │ ├── blockbag.h
│ │ │ │ ├── blockpool.h
│ │ │ │ ├── debug_info.h
│ │ │ │ ├── debugcounter.h
│ │ │ │ ├── debugprinting.h
│ │ │ │ ├── globals.h
│ │ │ │ ├── hashtable.h
│ │ │ │ ├── lockfreeblockbag.h
│ │ │ │ ├── pool_interface.h
│ │ │ │ ├── pool_none.h
│ │ │ │ ├── pool_perthread_and_shared.h
│ │ │ │ ├── reclaimer_debra.h
│ │ │ │ ├── reclaimer_debraplus.h
│ │ │ │ ├── reclaimer_hazardptr.h
│ │ │ │ ├── reclaimer_interface.h
│ │ │ │ ├── reclaimer_none.h
│ │ │ │ ├── reclaimer_rcu.h
│ │ │ │ ├── record_manager.h
│ │ │ │ ├── record_manager_single_type.h
│ │ │ │ └── recovery_manager.h
│ │ │ ├── rq/
│ │ │ │ ├── rq_dcssp.h
│ │ │ │ ├── rq_debugging.h
│ │ │ │ ├── rq_htm_rwlock.h
│ │ │ │ ├── rq_provider.h
│ │ │ │ ├── rq_rwlock.h
│ │ │ │ ├── rq_snapcollector.h
│ │ │ │ ├── rq_unsafe.h
│ │ │ │ └── snapcollector/
│ │ │ │ ├── reportitem.h
│ │ │ │ ├── snapcollector.h
│ │ │ │ └── snapcollector_test.cpp
│ │ │ └── rwlock.h
│ │ ├── ds/
│ │ │ └── brown_ext_abtree_lf/
│ │ │ ├── brown_ext_abtree_lf.h
│ │ │ ├── brown_ext_abtree_lf_adapter.h
│ │ │ └── brown_ext_abtree_lf_impl.h
│ │ └── minimal_example.cpp
│ └── trevor_brown_natarajan/
│ ├── TrevorBrownNatarajanTree.hpp
│ └── ds/
│ └── natarajan_ext_bst_lf/
│ ├── natarajan_ext_bst_lf_adapter.h
│ ├── natarajan_ext_bst_lf_stage1.h
│ └── natarajan_ext_bst_lf_stage2_impl.h
├── graphs/
│ ├── BenchmarkLatencyCounter.hpp
│ ├── BenchmarkLatencyQueues.hpp
│ ├── BenchmarkMaps.hpp
│ ├── BenchmarkQueues.hpp
│ ├── BenchmarkSPS.hpp
│ ├── BenchmarkSets.hpp
│ ├── Makefile
│ ├── PBenchmarkQueues.hpp
│ ├── PBenchmarkSPS.hpp
│ ├── PBenchmarkSets.hpp
│ ├── README.md
│ ├── bin/
│ │ └── .gitignore
│ ├── data/
│ │ └── README.md
│ ├── latency-counter.cpp
│ ├── lib/
│ │ └── .gitignore
│ ├── plots/
│ │ ├── caption.gp
│ │ ├── latency-counter.gp
│ │ ├── pcaption.gp
│ │ ├── plot-all.sh
│ │ ├── plot.sh
│ │ ├── pq-enq-deq.gp
│ │ ├── pq-ll-enq-deq.gp
│ │ ├── pset-hash-1k.gp
│ │ ├── pset-ll-1k.gp
│ │ ├── pset-tree-1k.gp
│ │ ├── pset-tree-1m.gp
│ │ ├── psps-integer.gp
│ │ ├── q-array-enq-deq.gp
│ │ ├── q-enq-deq.gp
│ │ ├── q-ll-enq-deq.gp
│ │ ├── set-hash-1k.gp
│ │ ├── set-ll-10k.gp
│ │ ├── set-ll-1k.gp
│ │ ├── set-tree-10k.gp
│ │ ├── set-tree-1k.gp
│ │ ├── sps-integer.gp
│ │ ├── sps-object.gp
│ │ ├── stress-multi-process-q.gp
│ │ └── styles.inc
│ ├── pq-ll-enq-deq.cpp
│ ├── pread-while-writing.cpp
│ ├── pset-hash-1k.cpp
│ ├── pset-ll-10k.cpp
│ ├── pset-ll-1k.cpp
│ ├── pset-tree-1k.cpp
│ ├── pset-tree-1m.cpp
│ ├── psps-integer.cpp
│ ├── q-array-enq-deq.cpp
│ ├── q-ll-enq-deq.cpp
│ ├── run-all-aws.sh
│ ├── set-hash-1k.cpp
│ ├── set-ll-10k.cpp
│ ├── set-ll-1k.cpp
│ ├── set-tree-10k.cpp
│ ├── set-tree-1k.cpp
│ ├── set-tree-1m.cpp
│ ├── sps-integer.cpp
│ └── sps-object.cpp
├── pdatastructures/
│ ├── README.md
│ ├── TMHashMap.hpp
│ ├── TMHashMapByRef.hpp
│ ├── TMLinkedListQueue.hpp
│ ├── TMLinkedListSet.hpp
│ ├── TMLinkedListSetByRef.hpp
│ ├── TMRedBlackTree.hpp
│ ├── TMRedBlackTreeByRef.hpp
│ └── pqueues/
│ ├── HazardPointers.hpp
│ ├── MichaelScottQueue.hpp
│ ├── PFriedmanQueue.hpp
│ ├── PMDKLinkedListQueue.hpp
│ ├── PMichaelScottQueue.hpp
│ ├── POFLFLinkedListQueue.hpp
│ ├── POFLFMPLinkedListQueue.hpp
│ ├── POFWFLinkedListQueue.hpp
│ ├── RomLRLinkedListQueue.hpp
│ └── RomLogLinkedListQueue.hpp
├── ptms/
│ ├── OneFilePTMLF.hpp
│ ├── OneFilePTMLFMultiProcess.hpp
│ ├── OneFilePTMWF.hpp
│ ├── PMDKTM.hpp
│ ├── README.md
│ ├── atlas/
│ │ ├── README.md
│ │ └── atlas.patch
│ ├── romuluslog/
│ │ ├── RomulusLog.cpp
│ │ ├── RomulusLog.hpp
│ │ └── malloc.cpp
│ ├── romuluslr/
│ │ ├── RomulusLR.cpp
│ │ ├── RomulusLR.hpp
│ │ └── malloc.cpp
│ └── rwlocks/
│ ├── CRWWP.hpp
│ └── CRWWP_SpinLock.hpp
└── stms/
├── CRWWPSTM.hpp
├── ESTM.hpp
├── OneFileLF.hpp
├── OneFileWF.hpp
├── TinySTM.hpp
├── estm-0.3.0/
│ ├── .gitignore
│ ├── AUTHORS
│ ├── COPYING
│ ├── Makefile
│ ├── Makefile.in
│ ├── README
│ ├── VERSIONS
│ ├── include/
│ │ ├── mod_local.h
│ │ ├── mod_mem.h
│ │ ├── mod_print.h
│ │ ├── mod_stats.h
│ │ ├── stm.h
│ │ └── wrappers.h
│ └── src/
│ ├── atomic.h
│ ├── atomic_ops/
│ │ ├── AUTHORS
│ │ ├── COPYING
│ │ ├── README
│ │ ├── aligned_atomic_load_store.h
│ │ ├── all_acquire_release_volatile.h
│ │ ├── ao_t_is_int.h
│ │ ├── atomic_ops.h
│ │ ├── generalize-small.h
│ │ ├── generalize.h
│ │ ├── ia64.h
│ │ ├── ordered_except_wr.h
│ │ ├── powerpc.h
│ │ ├── read_ordered.h
│ │ ├── sparc.h
│ │ ├── standard_ao_double_t.h
│ │ ├── test_and_set_t_is_ao_t.h
│ │ ├── test_and_set_t_is_char.h
│ │ ├── x86.h
│ │ └── x86_64.h
│ ├── gc.c
│ ├── gc.h
│ ├── mod_local.c
│ ├── mod_mem.c
│ ├── mod_print.c
│ ├── mod_stats.c
│ ├── stm.c
│ └── wrappers.c
└── tinystm/
├── ChangeLog
├── Doxyfile
├── GNU-LICENSE.txt
├── MIT-LICENSE.txt
├── Makefile
├── Makefile.clang
├── Makefile.common
├── Makefile.gcc
├── Makefile.icc
├── Makefile.suncc
├── README.md
├── abi/
│ ├── Makefile
│ ├── Makefile.common
│ ├── abi.c
│ ├── arch_x86.S
│ ├── dtmc/
│ │ ├── Makefile
│ │ ├── arch.S
│ │ ├── libitm.h
│ │ ├── libtanger-stm.public-symbols
│ │ ├── libtanger-stm.support
│ │ ├── tanger-stm-internal.h
│ │ ├── tanger.c
│ │ ├── tanger.h
│ │ └── tm_macros.h
│ ├── gcc/
│ │ ├── Makefile
│ │ ├── alloc_cpp.c
│ │ ├── arch.S
│ │ ├── clone.c
│ │ ├── eh.c
│ │ ├── libitm.h
│ │ └── tm_macros.h
│ ├── intel/
│ │ ├── Makefile
│ │ ├── alloc.c
│ │ ├── arch.S
│ │ ├── libitm.h
│ │ └── tm_macros.h
│ ├── libitm.h.tpl.cpp
│ ├── libitm.h.tpl.footer
│ ├── libitm.h.tpl.header
│ ├── libitm.h.tpl.unifdef
│ ├── oracle/
│ │ ├── Makefile
│ │ ├── arch.S
│ │ └── otm.c
│ ├── pthread_wrapper.h
│ ├── test/
│ │ └── Makefile
│ └── tm_macros.h
├── include/
│ ├── mod_ab.h
│ ├── mod_cb.h
│ ├── mod_log.h
│ ├── mod_mem.h
│ ├── mod_order.h
│ ├── mod_print.h
│ ├── mod_stats.h
│ ├── stm.h
│ └── wrappers.h
├── lib/
│ └── .gitignore
├── src/
│ ├── .gitignore
│ ├── atomic.h
│ ├── atomic_ops/
│ │ ├── AUTHORS
│ │ ├── COPYING
│ │ ├── README
│ │ ├── aligned_atomic_load_store.h
│ │ ├── all_acquire_release_volatile.h
│ │ ├── ao_t_is_int.h
│ │ ├── atomic_ops.h
│ │ ├── generalize-small.h
│ │ ├── generalize.h
│ │ ├── ia64.h
│ │ ├── ordered_except_wr.h
│ │ ├── powerpc.h
│ │ ├── read_ordered.h
│ │ ├── sparc.h
│ │ ├── standard_ao_double_t.h
│ │ ├── test_and_set_t_is_ao_t.h
│ │ ├── test_and_set_t_is_char.h
│ │ ├── x86.h
│ │ └── x86_64.h
│ ├── gc.c
│ ├── gc.h
│ ├── mod_ab.c
│ ├── mod_cb_mem.c
│ ├── mod_log.c
│ ├── mod_order.c
│ ├── mod_print.c
│ ├── mod_stats.c
│ ├── stm.c
│ ├── stm_internal.h
│ ├── stm_wbctl.h
│ ├── stm_wbetl.h
│ ├── stm_wt.h
│ ├── tls.h
│ ├── utils.h
│ └── wrappers.c
└── test/
├── Makefile
├── intset/
│ ├── .gitignore
│ ├── Makefile
│ ├── README.rbtree
│ ├── intset.c
│ ├── rbtree.c
│ ├── rbtree.h
│ ├── tm.h
│ └── types.h
└── regression/
├── .gitignore
├── Makefile
├── irrevocability.c
├── perf.c
└── types.c
Showing preview only (315K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3769 symbols across 288 files)
FILE: common/HazardEras.hpp
class HazardEras (line 57) | class HazardEras {
method HazardEras (line 74) | HazardEras(int maxHEs=MAX_HES, int maxThreads=HE_MAX_THREADS) : maxHEs...
method getEra (line 97) | inline uint64_t getEra() {
method clear (line 105) | inline void clear(const int tid) {
method T (line 115) | inline T* get_protected(int index, const std::atomic<T*>& atom, const ...
method protectEraRelease (line 126) | inline void protectEraRelease(int index, int other, const int tid) {
method T (line 139) | inline T* protectPtr(int index, const std::atomic<T*>& atom, uint64_t&...
method retire (line 155) | void retire(T* ptr, const int mytid) {
method canDelete (line 173) | bool canDelete(T* obj, const int mytid) {
FILE: common/HazardPointers.hpp
class HazardPointers (line 43) | class HazardPointers {
method HazardPointers (line 60) | HazardPointers(int maxHPs=MAX_HPS, int maxThreads=MAX_THREADS) : maxHP...
method clear (line 101) | void clear(const int tid) {
method clearOne (line 111) | void clearOne(int ihp, const int tid) {
method T (line 119) | T* protect(int index, const std::atomic<T*>& atom, const int tid) {
method T (line 129) | inline T* get_protected(int index, const std::atomic<T*>& atom, const ...
method T (line 137) | T* protectPtr(int index, T* ptr, const int tid) {
method protectHead (line 145) | void protectHead(int combinedIndex, T* lhead) {
method T (line 157) | T* protectRelease(int index, T* ptr, const int tid) {
method retire (line 166) | void retire(T* ptr, const int tid) {
method copyPtr (line 172) | void copyPtr(int index, int other, const int tid) {
method scanAndDelete (line 179) | void scanAndDelete(const int tid) {
FILE: common/HazardPointersSimQueue.hpp
class HazardPointersSimQueue (line 47) | class HazardPointersSimQueue {
method HazardPointersSimQueue (line 66) | HazardPointersSimQueue(std::function<bool(T*)>& find, int maxHPs=HP_MA...
method clear (line 88) | void clear(const int tid) {
method clearOne (line 98) | void clearOne(int ihp, const int tid) {
method T (line 106) | T* protect(int index, const std::atomic<T*>& atom, const int tid) {
method T (line 120) | T* protectPtr(int index, T* ptr, const int tid) {
method T (line 130) | T* protectRelease(int index, T* ptr, const int tid) {
method retire (line 140) | void retire(T* ptr, const int tid) {
FILE: common/RIStaticPerThread.hpp
class RIStaticPerThread (line 40) | class RIStaticPerThread {
method RIStaticPerThread (line 51) | RIStaticPerThread(int maxThreads) : maxThreads{maxThreads} {
method abortRollback (line 63) | inline void abortRollback() noexcept {
method rollbackArrive (line 74) | inline bool rollbackArrive(const int tid) noexcept {
method arrive (line 78) | inline void arrive(const int tid) noexcept {
method depart (line 82) | inline void depart(const int tid) noexcept {
method isEmpty (line 86) | inline bool isEmpty() noexcept {
FILE: common/ThreadRegistry.cpp
function thread_registry_deregister_thread (line 13) | void thread_registry_deregister_thread(const int tid) {
FILE: common/ThreadRegistry.hpp
type ThreadCheckInCheckOut (line 17) | struct ThreadCheckInCheckOut {
class ThreadRegistry (line 31) | class ThreadRegistry
method ThreadRegistry (line 51) | ThreadRegistry() {
method register_thread_new (line 60) | int register_thread_new(void) {
method deregister_thread (line 81) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 88) | static inline uint64_t getMaxThreads(void) {
method getTID (line 95) | static inline int getTID(void) {
class ThreadRegistry (line 45) | class ThreadRegistry {
method ThreadRegistry (line 51) | ThreadRegistry() {
method register_thread_new (line 60) | int register_thread_new(void) {
method deregister_thread (line 81) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 88) | static inline uint64_t getMaxThreads(void) {
method getTID (line 95) | static inline int getTID(void) {
FILE: common/pfences.h
function asm_rdtsc (line 30) | static inline unsigned long long asm_rdtsc(void)
function emulate_latency_ns (line 42) | static inline void emulate_latency_ns(int ns) {
function flushFromTo (line 102) | inline static void flushFromTo(void* from, void* to) noexcept {
FILE: datastructures/generic/TMHashMap.hpp
class TMHashMap (line 52) | class TMHashMap : public TM_BASE_TYPE {
type KeyVal (line 61) | struct KeyVal {
method KeyVal (line 65) | KeyVal() {}
method KeyVal (line 66) | KeyVal(K* key, V* value) : key{key}, val{value} { }
type Node (line 69) | struct Node : TM_BASE_TYPE {
method Node (line 72) | Node() {}
method Node (line 73) | Node(K* key, V* value) {
method isEmpty (line 77) | bool isEmpty() {
method myhash (line 88) | int myhash(K* key) { return 0; }
method TMHashMap (line 91) | TMHashMap(unsigned int maxThreads=MAX_THREADS, unsigned int capacity=2...
method className (line 101) | std::string className() { return TM_NAME() + "-HashMap"; }
method V (line 109) | V* put(K* key, V* value, const int tid) {
method V (line 152) | V* removeKey(K* key, const int tid) {
method V (line 184) | V* get(K* key, const int tid) {
method add (line 206) | bool add(K* key, const int tid) {
method remove (line 212) | bool remove(K* key, const int tid) {
method contains (line 218) | bool contains(K* key, const int tid) {
method addAll (line 225) | bool addAll(K** keys, const int size, const int tid) {
FILE: datastructures/generic/TMLinkedListQueue.hpp
class TMLinkedListQueue (line 62) | class TMLinkedListQueue {
type Node (line 68) | struct Node : TM_BASE_TYPE {
method Node (line 71) | Node(T* userItem) : item{userItem}, next{nullptr} { }
method TMLinkedListQueue (line 79) | TMLinkedListQueue(unsigned int maxThreads=MAX_THREADS) : maxThreads{ma...
method className (line 94) | static std::string className() { return TM_NAME() + "-LinkedListQueue"; }
method enqueue (line 101) | bool enqueue(T* item, const int tid) {
method T (line 115) | T* dequeue(const int tid) {
FILE: datastructures/generic/TMLinkedListSet.hpp
class TMLinkedListSet (line 48) | class TMLinkedListSet : public TM_BASE_TYPE {
type Node (line 54) | struct Node : public TM_BASE_TYPE {
method Node (line 57) | Node(T* key) : key{key}, next{nullptr} { }
method TMLinkedListSet (line 65) | TMLinkedListSet(unsigned int maxThreads=MAX_THREADS) : maxThreads{maxT...
method className (line 88) | static std::string className() { return TM_NAME() + "-LinkedListSet"; }
method add (line 95) | bool add(T* key, const int tid) {
method remove (line 131) | bool remove(T* key, const int tid) {
method contains (line 158) | bool contains(T* key, const int tid) {
method add (line 179) | bool add(T* key, const int tid) {
method remove (line 206) | bool remove(T* key, const int tid) {
method contains (line 230) | bool contains(T* key, const int tid) {
method addAll (line 244) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/generic/TMRedBlackBST.hpp
class TMRedBlackBST (line 15) | class TMRedBlackBST : public TM_BASE_TYPE {
type Node (line 17) | struct Node : TM_BASE_TYPE {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method assignAndFreeIfNull (line 31) | inline void assignAndFreeIfNull(TM_TYPE<Node*>& z, Node* w) {
method TMRedBlackBST (line 41) | TMRedBlackBST(unsigned int maxThreads=128) : maxThreads{maxThreads} { }
method isRed (line 47) | bool isRed(Node* x) {
method size (line 53) | int size(Node* x) {
method size (line 63) | int size() {
method isEmpty (line 71) | bool isEmpty() {
method V (line 87) | V* get(K* key) {
method V (line 93) | V* get(Node* x, K* key) {
method contains (line 109) | bool contains(K* key) {
method put (line 127) | void put(K* key, V* val) {
method Node (line 139) | Node* put(Node* h, K* key, V* val) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method deleteMin (line 161) | void deleteMin() {
method Node (line 172) | Node* deleteMin(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method deleteMax (line 186) | void deleteMax() {
method Node (line 199) | Node* deleteMax(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method deleteKey (line 221) | void deleteKey(K* key) {
method Node (line 233) | Node* deleteKey(Node* h, K* key) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method Node (line 269) | Node* rotateRight(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method Node (line 282) | Node* rotateLeft(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method flipColors (line 295) | void flipColors(Node* h) {
method Node (line 307) | Node* moveRedLeft(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method Node (line 322) | Node* moveRedRight(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method Node (line 334) | Node* balance(Node* h) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method height (line 354) | int height() {
method height (line 357) | int height(Node* x) {
method K (line 371) | K* min() {
method Node (line 377) | Node* min(Node* x) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method K (line 388) | K* max() {
method Node (line 394) | Node* max(Node* x) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method K (line 408) | K* floor(K* key) {
method Node (line 417) | Node* floor(Node* x, K* key) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method K (line 433) | K* ceiling(K* key) {
method Node (line 442) | Node* ceiling(Node* x, K* key) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method K (line 458) | K* select(int k) {
method Node (line 467) | Node* select(Node* x, int k) {
method Node (line 24) | Node(K* key, V* val, int64_t color, int64_t size) : key{key}, val{va...
method rank (line 482) | int rank(K* key) {
method rank (line 488) | int rank(K* key, Node* x) {
method size (line 510) | int size(K* lo, K* hi) {
method check (line 523) | bool check() {
method isBST (line 534) | bool isBST() {
method isBST (line 541) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 550) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 551) | bool isSizeConsistent(Node* x) {
method is23 (line 570) | bool is23() { return is23(root); }
method is23 (line 571) | bool is23(Node* x) {
method isBalanced (line 580) | bool isBalanced() {
method isBalanced (line 591) | bool isBalanced(Node* x, int black) {
method add (line 600) | bool add(K* key, const int tid) {
method remove (line 608) | bool remove(K* key, const int tid) {
method contains (line 616) | inline bool contains(K* key, const int tid) {
method addAll (line 624) | bool addAll(K** keys, int size, const int tid) {
method className (line 628) | std::string className() { return TM_NAME() + "-RedBlackBST"; }
FILE: datastructures/hashmaps/CRWWPSTMResizableHashSet.hpp
class CRWWPSTMResizableHashSet (line 23) | class CRWWPSTMResizableHashSet {
type Node (line 26) | struct Node : public crwwpstm::tmbase {
method Node (line 29) | Node(const K& k) : key{k} { }
method CRWWPSTMResizableHashSet (line 39) | CRWWPSTMResizableHashSet(int maxThreads=0, int capacity=4) : capacity{...
method className (line 62) | static std::string className() { return crwwpstm::CRWWPSTM::className(...
method rebuild (line 65) | void rebuild() {
method innerPut (line 91) | bool innerPut(const K& key) {
method innerRemove (line 120) | bool innerRemove(const K& key) {
method innerGet (line 145) | bool innerGet(const K& key) {
method add (line 161) | bool add(K key, const int tid=0) {
method remove (line 168) | bool remove(K key, const int tid=0) {
method contains (line 174) | bool contains(K key, const int tid=0) {
method addAll (line 181) | void addAll(K** keys, const int size, const int tid=0) {
FILE: datastructures/hashmaps/ESTMResizableHashSet.hpp
class ESTMResizableHashSet (line 23) | class ESTMResizableHashSet {
type Node (line 26) | struct Node : public estm::tmbase {
method Node (line 29) | Node(const K& k) : key{k} { }
method ESTMResizableHashSet (line 39) | ESTMResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity...
method className (line 62) | static std::string className() { return estm::ESTM::className() + "-Ha...
method rebuild (line 65) | void rebuild() {
method innerPut (line 91) | bool innerPut(const K& key) {
method innerRemove (line 120) | bool innerRemove(const K& key) {
method innerGet (line 145) | bool innerGet(const K& key) {
method add (line 161) | bool add(K key, const int tid=0) {
method remove (line 168) | bool remove(K key, const int tid=0) {
method contains (line 174) | bool contains(K key, const int tid=0) {
method addAll (line 181) | void addAll(K** keys, const int size, const int tid=0) {
FILE: datastructures/hashmaps/OFLFResizableHashSet.hpp
class OFLFResizableHashSet (line 23) | class OFLFResizableHashSet {
type Node (line 26) | struct Node : public oflf::tmbase {
method Node (line 29) | Node(const K& k) : key{k} { }
method OFLFResizableHashSet (line 39) | OFLFResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity...
method className (line 62) | static std::string className() { return oflf::OneFileLF::className() +...
method rebuild (line 65) | void rebuild() {
method innerPut (line 91) | bool innerPut(const K& key) {
method innerRemove (line 120) | bool innerRemove(const K& key) {
method innerGet (line 145) | bool innerGet(const K& key) {
method add (line 161) | bool add(K key, const int tid=0) {
method remove (line 168) | bool remove(K key, const int tid=0) {
method contains (line 174) | bool contains(K key, const int tid=0) {
method addAll (line 181) | void addAll(K** keys, const int size, const int tid=0) {
FILE: datastructures/hashmaps/OFWFResizableHashSet.hpp
class OFWFResizableHashSet (line 23) | class OFWFResizableHashSet {
type Node (line 26) | struct Node : public ofwf::tmbase {
method Node (line 29) | Node(const K& k) : key{k} { }
method OFWFResizableHashSet (line 39) | OFWFResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capacity...
method className (line 62) | static std::string className() { return ofwf::OneFileWF::className() +...
method rebuild (line 65) | void rebuild() {
method innerPut (line 91) | bool innerPut(const K& key) {
method innerRemove (line 120) | bool innerRemove(const K& key) {
method innerGet (line 145) | bool innerGet(const K& key) {
method add (line 161) | bool add(K key, const int tid=0) {
method remove (line 168) | bool remove(K key, const int tid=0) {
method contains (line 174) | bool contains(K key, const int tid=0) {
method addAll (line 181) | void addAll(K** keys, const int size, const int tid=0) {
FILE: datastructures/hashmaps/TinySTMResizableHashSet.hpp
class TinySTMResizableHashSet (line 23) | class TinySTMResizableHashSet {
type Node (line 26) | struct Node : public tinystm::tmbase {
method Node (line 29) | Node(const K& k) : key{k} { }
method TinySTMResizableHashSet (line 39) | TinySTMResizableHashSet(int maxThreads=0, uint64_t capacity=4) : capac...
method className (line 64) | static std::string className() { return tinystm::TinySTM::className() ...
method rebuild (line 67) | void rebuild() {
method innerPut (line 93) | bool innerPut(const K& key) {
method innerRemove (line 122) | bool innerRemove(const K& key) {
method innerGet (line 147) | bool innerGet(const K& key) {
method add (line 163) | bool add(K key, const int tid=0) {
method remove (line 170) | bool remove(K key, const int tid=0) {
method contains (line 176) | bool contains(K key, const int tid=0) {
method addAll (line 183) | void addAll(K** keys, const int size, const int tid=0) {
FILE: datastructures/linkedlists/CRWWPLinkedListSet.hpp
class CRWWPLinkedListSet (line 47) | class CRWWPLinkedListSet : public crwwpstm::tmbase {
type Node (line 50) | struct Node : public crwwpstm::tmbase {
method Node (line 53) | Node() {}
method Node (line 54) | Node(T key) : key{key} { }
method CRWWPLinkedListSet (line 62) | CRWWPLinkedListSet(unsigned int maxThreads=0) {
method className (line 85) | static std::string className() { return crwwpstm::CRWWPSTM::className(...
method add (line 92) | bool add(T key, const int tid=0) {
method remove (line 118) | bool remove(T key, const int tid=0) {
method contains (line 141) | bool contains(T key, const int tid=0) {
method addAll (line 154) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/linkedlists/ESTMLinkedListSet.hpp
class ESTMLinkedListSet (line 22) | class ESTMLinkedListSet : public estm::tmbase {
type Node (line 25) | struct Node : public estm::tmbase {
method Node (line 28) | Node() {}
method Node (line 29) | Node(T key) : key{key} { }
method ESTMLinkedListSet (line 37) | ESTMLinkedListSet(unsigned int maxThreads=0) {
method className (line 64) | static std::string className() { return estm::ESTM::className() + "-Li...
method add (line 71) | bool add(T key, const int tid=0) {
method remove (line 97) | bool remove(T key, const int tid=0) {
method contains (line 120) | bool contains(T key, const int tid=0) {
method addAll (line 133) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/linkedlists/HazardEras.hpp
class HazardEras (line 56) | class HazardEras {
method HazardEras (line 74) | HazardEras(int maxHEs=MAX_HES, int maxThreads=HE_MAX_THREADS) : maxHEs...
method getEra (line 97) | inline uint64_t getEra() {
method clear (line 105) | inline void clear(const int tid) {
method T (line 115) | inline T* get_protected(int index, const std::atomic<T*>& atom, const ...
method protectEraRelease (line 126) | inline void protectEraRelease(int index, int other, const int tid) {
method T (line 139) | inline T* protectPtr(int index, const std::atomic<T*>& atom, uint64_t&...
method retire (line 157) | void retire(T* ptr, const int mytid) {
method canDelete (line 175) | bool canDelete(T* obj, const int mytid) {
FILE: datastructures/linkedlists/HazardPointers.hpp
class HazardPointers (line 39) | class HazardPointers {
method HazardPointers (line 56) | HazardPointers(int maxHPs=HP_MAX_HPS, int maxThreads=HP_MAX_THREADS) :...
method clear (line 80) | inline void clear(const int tid) {
method clearOne (line 90) | inline void clearOne(int ihp, const int tid) {
method T (line 98) | inline T* protect(int index, const std::atomic<T*>& atom, const int ti...
method T (line 113) | inline T* protectPtr(int index, T* ptr, const int tid) {
method T (line 129) | inline T* protectPtrRelease(int index, T* ptr, const int tid) {
method retire (line 138) | void retire(T* ptr, const int tid) {
FILE: datastructures/linkedlists/MagedHarrisLinkedListSetHE.hpp
class MagedHarrisLinkedListSetHE (line 59) | class MagedHarrisLinkedListSetHE {
type Node (line 62) | struct Node {
method Node (line 68) | Node(T key, uint64_t newEra) : key{key}, newEra{newEra}, delEra{0}, ...
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
method MagedHarrisLinkedListSetHE (line 88) | MagedHarrisLinkedListSetHE(const int maxThreads) : maxThreads{maxThrea...
method className (line 107) | static std::string className() { return "MagedHarris-LinkedListSetHE"; }
method addAll (line 113) | void addAll(T** keys, const int size, const int tid) {
method add (line 132) | bool add(T key, const int tid)
method remove (line 158) | bool remove(T key, const int tid)
method contains (line 198) | bool contains(T key, const int tid)
method find (line 214) | bool find (T* key, std::atomic<Node*> **par_prev, Node **par_curr, Nod...
method isMarked (line 256) | bool isMarked(Node * node) {
method Node (line 260) | Node * getMarked(Node * node) {
method Node (line 68) | Node(T key, uint64_t newEra) : key{key}, newEra{newEra}, delEra{0}, ...
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
method Node (line 264) | Node * getUnmarked(Node * node) {
method Node (line 68) | Node(T key, uint64_t newEra) : key{key}, newEra{newEra}, delEra{0}, ...
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
FILE: datastructures/linkedlists/MagedHarrisLinkedListSetHP.hpp
class MagedHarrisLinkedListSetHP (line 61) | class MagedHarrisLinkedListSetHP {
type Node (line 64) | struct Node {
method Node (line 68) | Node(T key) : key{key}, next{nullptr} { }
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
method MagedHarrisLinkedListSetHP (line 89) | MagedHarrisLinkedListSetHP(const int maxThreads) : maxThreads{maxThrea...
method className (line 108) | static std::string className() { return "MagedHarris-LinkedListSetHP"; }
method addAll (line 114) | void addAll(T** keys, const int size, const int tid) {
method add (line 133) | bool add(T key, const int tid)
method remove (line 159) | bool remove(T key, const int tid)
method contains (line 199) | bool contains(T key, const int tid)
method find (line 216) | bool find (T* key, std::atomic<Node*> **par_prev, Node **par_curr, Nod...
method isMarked (line 261) | bool isMarked(Node * node) {
method Node (line 265) | Node * getMarked(Node * node) {
method Node (line 68) | Node(T key) : key{key}, next{nullptr} { }
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
method Node (line 269) | Node * getUnmarked(Node * node) {
method Node (line 68) | Node(T key) : key{key}, next{nullptr} { }
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
FILE: datastructures/linkedlists/OFLFLinkedListSet.hpp
class OFLFLinkedListSet (line 22) | class OFLFLinkedListSet : public oflf::tmbase {
type Node (line 25) | struct Node : public oflf::tmbase {
method Node (line 28) | Node() {}
method Node (line 29) | Node(T key) : key{key} { }
method OFLFLinkedListSet (line 37) | OFLFLinkedListSet(unsigned int maxThreads=0) {
method className (line 64) | static std::string className() { return oflf::OneFileLF::className() +...
method add (line 71) | bool add(T key, const int tid=0) {
method remove (line 99) | bool remove(T key, const int tid=0) {
method contains (line 124) | bool contains(T key, const int tid=0) {
method addAll (line 139) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/linkedlists/OFWFLinkedListSet.hpp
class OFWFLinkedListSet (line 22) | class OFWFLinkedListSet : public ofwf::tmbase {
type Node (line 25) | struct Node : public ofwf::tmbase {
method Node (line 28) | Node(T key) : key{key} { }
method Node (line 29) | Node() {}
method OFWFLinkedListSet (line 37) | OFWFLinkedListSet(unsigned int maxThreads=0) {
method className (line 64) | static std::string className() { return ofwf::OneFileWF::className() +...
method add (line 71) | bool add(T key, const int tid=0) {
method remove (line 99) | bool remove(T key, const int tid=0) {
method contains (line 124) | bool contains(T key, const int tid=0) {
method addAll (line 139) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/linkedlists/STMLinkedListSet.hpp
class STMLinkedListSet (line 47) | class STMLinkedListSet : public TMBASE {
type Node (line 50) | struct Node : public TMBASE {
method Node (line 53) | Node(T* key) : key{key}, next{nullptr} { }
method STMLinkedListSet (line 61) | STMLinkedListSet(unsigned int maxThreads=0) {
method className (line 84) | static std::string className() { return TM::className() + "-LinkedList...
method add (line 91) | bool add(T* key, const int tid=0) {
method remove (line 118) | bool remove(T* key, const int tid=0) {
method contains (line 142) | bool contains(T* key, const int tid=0) {
method addAll (line 156) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/linkedlists/TinySTMLinkedListSet.hpp
class TinySTMLinkedListSet (line 20) | class TinySTMLinkedListSet : public tinystm::tmbase {
type Node (line 23) | struct Node : public tinystm::tmbase {
method Node (line 26) | Node() {}
method Node (line 27) | Node(T key) : key{key} { }
method TinySTMLinkedListSet (line 35) | TinySTMLinkedListSet(unsigned int maxThreads=0) {
method className (line 64) | static std::string className() { return "TinySTM-LinkedListSet"; }
method add (line 71) | bool add(T key, const int tid=0) {
method remove (line 99) | bool remove(T key, const int tid=0) {
method contains (line 124) | bool contains(T key, const int tid=0) {
method addAll (line 139) | bool addAll(T** keys, int size, const int tid) {
FILE: datastructures/queues/CRWWPLinkedListQueue.hpp
class CRWWPLinkedListQueue (line 57) | class CRWWPLinkedListQueue {
type Node (line 60) | struct Node : crwwpstm::tmbase {
method Node (line 63) | Node(T* userItem) : item{userItem}, next{nullptr} { }
method CRWWPLinkedListQueue (line 71) | CRWWPLinkedListQueue(unsigned int maxThreads=0) {
method className (line 85) | static std::string className() { return "CRWWP-LinkedListQueue"; }
method enqueue (line 92) | bool enqueue(T* item, const int tid=0) {
method T (line 106) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/ESTMArrayLinkedListQueue.hpp
class ESTMArrayLinkedListQueue (line 56) | class ESTMArrayLinkedListQueue {
type Node (line 59) | struct Node : estm::tmbase {
method Node (line 65) | Node(T* item) {
method ESTMArrayLinkedListQueue (line 78) | ESTMArrayLinkedListQueue(unsigned int maxThreads=0) {
method className (line 99) | static std::string className() { return "ESTM-ArrayLinkedListQueue"; }
method enqueue (line 106) | bool enqueue(T* item, const int tid=0) {
method T (line 127) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/ESTMLinkedListQueue.hpp
class ESTMLinkedListQueue (line 47) | class ESTMLinkedListQueue {
type Node (line 50) | struct Node : estm::tmbase {
method Node (line 53) | Node(T* userItem) : item{userItem} { }
method ESTMLinkedListQueue (line 61) | ESTMLinkedListQueue(unsigned int maxThreads=0) {
method className (line 81) | static std::string className() { return "ESTM-LinkedListQueue"; }
method enqueue (line 88) | bool enqueue(T* item, const int tid=0) {
method T (line 102) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/FAAArrayQueue.hpp
class FAAArrayQueue (line 81) | class FAAArrayQueue {
type Node (line 85) | struct Node {
method Node (line 92) | Node(T* item) : deqidx{0}, enqidx{1}, next{nullptr} {
method casNext (line 99) | bool casNext(Node *cmp, Node *val) {
method casTail (line 104) | bool casTail(Node *cmp, Node *val) {
method casHead (line 108) | bool casHead(Node *cmp, Node *val) {
method FAAArrayQueue (line 128) | FAAArrayQueue(int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
method className (line 143) | static std::string className() { return "FAAArrayQueue"; }
method enqueue (line 146) | void enqueue(T* item, const int tid) {
method T (line 176) | T* dequeue(const int tid) {
FILE: datastructures/queues/HazardPointers.hpp
class HazardPointers (line 40) | class HazardPointers {
method HazardPointers (line 59) | HazardPointers(int maxHPs, int maxThreads) : maxHPs{maxHPs}, maxThread...
method HazardPointers (line 68) | HazardPointers(int maxHPs, int maxThreads, std::function<void(T*,int)>...
method clear (line 91) | void clear(const int tid) {
method clearOne (line 101) | void clearOne(int ihp, const int tid) {
method T (line 109) | T* protect(int index, const std::atomic<T*>& atom, const int tid) {
method T (line 119) | T* get(int index, const int tid){
method T (line 126) | T* protectPtr(int index, T* ptr, const int tid) {
method T (line 137) | T* protectPtrRelease(int index, T* ptr, const int tid) {
method retire (line 146) | void retire(T* ptr, const int tid) {
FILE: datastructures/queues/HazardPointersSimQueue.hpp
class HazardPointersSimQueue (line 41) | class HazardPointersSimQueue {
method HazardPointersSimQueue (line 60) | HazardPointersSimQueue(std::function<bool(T*)>& find, int maxHPs=HP_MA...
method clear (line 82) | void clear(const int tid) {
method clearOne (line 92) | void clearOne(int ihp, const int tid) {
method T (line 100) | T* protect(int index, const std::atomic<T*>& atom, const int tid) {
method T (line 114) | T* protectPtr(int index, T* ptr, const int tid) {
method T (line 124) | T* protectRelease(int index, T* ptr, const int tid) {
method retire (line 134) | void retire(T* ptr, const int tid) {
FILE: datastructures/queues/LCRQueue.hpp
class LCRQueue (line 94) | class LCRQueue {
type Cell (line 100) | struct Cell {
type Node (line 106) | struct Node {
method Node (line 112) | Node() {
method is_empty (line 137) | int is_empty(T* v) {
method node_index (line 141) | uint64_t node_index(uint64_t i) {
method set_unsafe (line 145) | uint64_t set_unsafe(uint64_t i) {
method node_unsafe (line 149) | uint64_t node_unsafe(uint64_t i) {
method tail_index (line 153) | inline uint64_t tail_index(uint64_t t) {
method crq_is_closed (line 157) | int crq_is_closed(uint64_t t) {
method fixState (line 161) | void fixState(Node *lhead) {
method close_crq (line 176) | int close_crq(Node *rq, const uint64_t tailticket, const int tries) {
method LCRQueue (line 188) | LCRQueue(int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
method className (line 201) | static std::string className() { return "LCRQueue"; }
method enqueue (line 204) | void enqueue(T* item, const int tid) {
method T (line 249) | T* dequeue(const int tid) {
FILE: datastructures/queues/MichaelScottQueue.hpp
class MichaelScottQueue (line 61) | class MichaelScottQueue {
type Node (line 64) | struct Node {
method Node (line 68) | Node(T* userItem) : item{userItem}, next{nullptr} { }
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
method casTail (line 75) | bool casTail(Node *cmp, Node *val) {
method casHead (line 79) | bool casHead(Node *cmp, Node *val) {
method MichaelScottQueue (line 97) | MichaelScottQueue(int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
method className (line 109) | static std::string className() { return "MichaelScottQueue"; }
method enqueue (line 111) | void enqueue(T* item, const int tid) {
method T (line 134) | T* dequeue(const int tid) {
FILE: datastructures/queues/OFLFArrayLinkedListQueue.hpp
class OFLFArrayLinkedListQueue (line 34) | class OFLFArrayLinkedListQueue : public oflf::tmbase {
type Node (line 43) | struct Node : oflf::tmbase {
method Node (line 50) | Node(T* item) {
method OFLFArrayLinkedListQueue (line 63) | OFLFArrayLinkedListQueue(unsigned int maxThreads=0) {
method className (line 78) | static std::string className() { return "OF-LF-ArrayLinkedListQueue"; }
method enqueue (line 85) | bool enqueue(T* item, const int tid=0) {
method T (line 106) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/OFLFArrayQueue.hpp
class OFLFArrayQueue (line 23) | class OFLFArrayQueue : public oflf::tmbase {
method OFLFArrayQueue (line 33) | OFLFArrayQueue(unsigned int maxThreads=0) {
method className (line 44) | static std::string className() { return "OF-LF-ArrayQueue"; }
method enqueue (line 51) | bool enqueue(T* item, const int tid=0) {
method T (line 65) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/OFLFLinkedListQueue.hpp
class OFLFLinkedListQueue (line 31) | class OFLFLinkedListQueue : public oflf::tmbase {
type Node (line 34) | struct Node : oflf::tmbase {
method Node (line 37) | Node(T* userItem) : item{userItem} { }
method OFLFLinkedListQueue (line 45) | OFLFLinkedListQueue(unsigned int maxThreads=0) {
method className (line 59) | static std::string className() { return "OF-LF-LinkedListQueue"; }
method enqueue (line 66) | bool enqueue(T* item, const int tid=0) {
method T (line 80) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/OFWFArrayLinkedListQueue.hpp
class OFWFArrayLinkedListQueue (line 34) | class OFWFArrayLinkedListQueue : public ofwf::tmbase {
type Node (line 37) | struct Node : ofwf::tmbase {
method Node (line 43) | Node(T* item) {
method OFWFArrayLinkedListQueue (line 56) | OFWFArrayLinkedListQueue(unsigned int maxThreads=0) {
method className (line 71) | static std::string className() { return "OF-WF-ArrayLinkedListQueue"; }
method enqueue (line 78) | bool enqueue(T* item, const int tid=0) {
method T (line 99) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/OFWFLinkedListQueue.hpp
class OFWFLinkedListQueue (line 31) | class OFWFLinkedListQueue : public ofwf::tmbase {
type Node (line 34) | struct Node : ofwf::tmbase {
method Node (line 37) | Node(T* userItem) : item{userItem}, next{nullptr} { }
method OFWFLinkedListQueue (line 45) | OFWFLinkedListQueue(unsigned int maxThreads=0) {
method className (line 59) | static std::string className() { return "OF-WF-LinkedListQueue"; }
method enqueue (line 66) | bool enqueue(T* item, const int tid=0) {
method T (line 80) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/SimQueue.hpp
class SimQueue (line 58) | class SimQueue {
type Node (line 63) | struct Node {
method Node (line 66) | Node(T* item) : item{item} { }
type EnqState (line 70) | struct EnqState {
method EnqState (line 76) | EnqState() {
type DeqState (line 84) | struct DeqState {
method DeqState (line 89) | DeqState() {
type StructData (line 99) | struct StructData{
method SimQueue (line 141) | SimQueue(int maxThreads=MAX_THREADS) : maxThreads(maxThreads) {
method className (line 171) | static std::string className() { return "SimQueue"; }
method enqueue (line 177) | void enqueue(T* item, const int tid) {
method T (line 246) | T* dequeue(const int tid) {
FILE: datastructures/queues/TinySTMArrayLinkedListQueue.hpp
class TinySTMArrayLinkedListQueue (line 41) | class TinySTMArrayLinkedListQueue {
type Node (line 44) | struct Node : tinystm::tmbase {
method Node (line 50) | Node(T* item) {
method TinySTMArrayLinkedListQueue (line 63) | TinySTMArrayLinkedListQueue(unsigned int maxThreads=0) {
method className (line 84) | static std::string className() { return "TinySTM-ArrayLinkedListQueue"; }
method enqueue (line 91) | bool enqueue(T* item, const int tid=0) {
method T (line 112) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/TinySTMLinkedListQueue.hpp
class TinySTMLinkedListQueue (line 42) | class TinySTMLinkedListQueue : public tinystm::tmbase {
type Node (line 45) | struct Node : tinystm::tmbase {
method Node (line 48) | Node(T* userItem) : item{userItem} { }
method TinySTMLinkedListQueue (line 56) | TinySTMLinkedListQueue(unsigned int maxThreads=0) {
method className (line 76) | static std::string className() { return "TinySTM-LinkedListQueue"; }
method enqueue (line 83) | bool enqueue(T* item, const int tid=0) {
method T (line 97) | T* dequeue(const int tid=0) {
FILE: datastructures/queues/TurnQueue.hpp
class TurnQueue (line 62) | class TurnQueue {
type Node (line 65) | struct Node {
method Node (line 71) | Node(T* item, int tid) : item{item}, enqTid{tid}, deqTid{IDX_NONE}, ...
method casDeqTid (line 73) | bool casDeqTid(int cmp, int val) {
method searchNext (line 107) | inline int searchNext(Node* lhead, Node* lnext) {
method casDeqAndHead (line 125) | inline void casDeqAndHead(Node* lhead, Node* lnext, const int tid) {
method giveUp (line 144) | inline void giveUp(Node* myReq, const int tid) {
method TurnQueue (line 156) | TurnQueue(int maxThreads=MAX_THREADS) : maxThreads(maxThreads) {
method className (line 176) | static std::string className() { return "TurnQueue"; }
method enqueue (line 188) | void enqueue(T* item, const int tid) {
method T (line 230) | T* dequeue(const int tid) {
FILE: datastructures/sequential/HashSet.hpp
class HashSet (line 41) | class HashSet {
method className (line 48) | static std::string className() { return "HashSet"; }
method add (line 51) | bool add(CKey key) {
method remove (line 59) | bool remove(CKey key) {
method contains (line 66) | bool contains(CKey key) {
method iterateAll (line 71) | bool iterateAll(std::function<bool(CKey*)> itfun) {
FILE: datastructures/sequential/LinkedListQueue.hpp
class LinkedListQueue (line 41) | class LinkedListQueue {
type Node (line 44) | struct Node {
method Node (line 47) | Node(T* userItem) : item{userItem} { }
method LinkedListQueue (line 55) | LinkedListQueue(unsigned int maxThreads=0) {
method LinkedListQueue (line 63) | LinkedListQueue(const LinkedListQueue& other) {
method className (line 83) | static std::string className() { return "LinkedListQueue"; }
method enqueue (line 86) | bool enqueue(T* item, const int tid=0) {
method T (line 95) | T* dequeue(const int tid=0) {
FILE: datastructures/sequential/LinkedListSet.hpp
class LinkedListSet (line 13) | class LinkedListSet {
type Node (line 17) | struct Node {
method Node (line 20) | Node(const K& key) : key{key}, next{nullptr} { }
method Node (line 21) | Node(){ }
method LinkedListSet (line 29) | LinkedListSet() {
method LinkedListSet (line 40) | LinkedListSet(const LinkedListSet& other) {
method className (line 68) | static std::string className() { return "LinkedListSet"; }
method add (line 74) | bool add(const K& key) {
method remove (line 89) | bool remove(const K& key) {
method contains (line 103) | bool contains(const K& key) {
method find (line 109) | void find(const K& key, Node*& prev, Node*& node) {
method addAll (line 116) | bool addAll(K** keys, const int size) {
FILE: datastructures/sequential/RedBlackBST.hpp
class RedBlackBST (line 11) | class RedBlackBST {
type Node (line 14) | struct Node {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method RedBlackBST (line 34) | RedBlackBST(unsigned int maxThreads=128) { }
method isRed (line 40) | bool isRed(Node* x) {
method size (line 46) | int size(Node* x) {
method size (line 56) | int size() {
method isEmpty (line 64) | bool isEmpty() {
method V (line 80) | V* get(K* key) {
method V (line 86) | V* get(Node* x, K* key) {
method contains (line 102) | bool contains(K* key) {
method put (line 120) | void put(K* key, V* val) {
method Node (line 133) | Node* put(Node* h, K* key, V* val) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method deleteMin (line 156) | void deleteMin() {
method Node (line 169) | Node* deleteMin(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method deleteMax (line 185) | void deleteMax() {
method Node (line 198) | Node* deleteMax(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method deleteKey (line 220) | void deleteKey(K* key) {
method Node (line 234) | Node* deleteKey(Node* h, K* key) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method Node (line 267) | Node* rotateRight(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method Node (line 280) | Node* rotateLeft(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method flipColors (line 293) | void flipColors(Node* h) {
method Node (line 305) | Node* moveRedLeft(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method Node (line 320) | Node* moveRedRight(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method Node (line 332) | Node* balance(Node* h) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method height (line 352) | int height() {
method height (line 355) | int height(Node* x) {
method K (line 369) | K* min() {
method Node (line 375) | Node* min(Node* x) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method K (line 386) | K* max() {
method Node (line 392) | Node* max(Node* x) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method K (line 406) | K* floor(K* key) {
method Node (line 415) | Node* floor(Node* x, K* key) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method K (line 431) | K* ceiling(K* key) {
method Node (line 440) | Node* ceiling(Node* x, K* key) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method K (line 457) | K* select(int k) {
method Node (line 466) | Node* select(Node* x, int k) {
method Node (line 21) | Node(K* key, V* val, bool color, int size) : key{key}, val{val}, col...
method rank (line 481) | int rank(K* key) {
method rank (line 487) | int rank(K* key, Node* x) {
method size (line 509) | int size(K* lo, K* hi) {
method check (line 522) | bool check() {
method isBST (line 533) | bool isBST() {
method isBST (line 540) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 548) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 549) | bool isSizeConsistent(Node* x) {
method is23 (line 568) | bool is23() { return is23(root); }
method is23 (line 569) | bool is23(Node* x) {
method isBalanced (line 578) | bool isBalanced() {
method isBalanced (line 589) | bool isBalanced(Node* x, int black) {
method add (line 598) | bool add(K* key, const int tid) {
method remove (line 604) | bool remove(K* key, const int tid) {
method contains (line 610) | inline bool contains(K* key, const int tid) {
method className (line 614) | std::string className() { return "RedBlackBST"; }
FILE: datastructures/sequential/SortedArraySet.hpp
class SortedArraySet (line 41) | class SortedArraySet {
method lookup (line 50) | int lookup(T* key) {
method SortedArraySet (line 79) | SortedArraySet() {
method SortedArraySet (line 88) | SortedArraySet(const SortedArraySet<T>& fromssv) {
method className (line 98) | static std::string className() { return "SortedArraySet"; }
method erase (line 100) | void erase(int index){
method remove (line 112) | bool remove(T* key) {
method add (line 131) | bool add(T* key) {
method contains (line 169) | bool contains(T* key) {
method print (line 179) | bool print() { // For debug purposes
FILE: datastructures/sequential/SortedVectorSet.hpp
class SortedVectorSet (line 42) | class SortedVectorSet {
method lookup (line 49) | int lookup(T* key) {
method SortedVectorSet (line 76) | SortedVectorSet() { }
method SortedVectorSet (line 79) | SortedVectorSet(const SortedVectorSet<T>& from) {
method className (line 83) | static std::string className() { return "SortedVectorSet"; }
method remove (line 88) | bool remove(T* key) {
method add (line 107) | bool add(T* key) {
method contains (line 123) | bool contains(T* key) {
method print (line 133) | bool print() { // For debug purposes
FILE: datastructures/sequential/TreeSet.hpp
class TreeSet (line 43) | class TreeSet {
method className (line 52) | static std::string className() { return "TreeSet"; }
method add (line 55) | bool add(CKey key) {
method remove (line 63) | bool remove(CKey key) {
method contains (line 70) | bool contains(CKey key) {
method iterateAll (line 75) | bool iterateAll(std::function<bool(CKey*)> itfunc) {
FILE: datastructures/treemaps/ESTMRedBlackTree.hpp
class ESTMRedBlackTree (line 12) | class ESTMRedBlackTree {
type Node (line 16) | struct Node {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method assignAndFreeIfNull (line 28) | inline void assignAndFreeIfNull(estm::tmtype<Node*>& z, Node* w) {
method ESTMRedBlackTree (line 38) | ESTMRedBlackTree(int maxThreads=0){ }
method isRed (line 55) | bool isRed(Node* x) {
method size (line 61) | int size(Node* x) {
method size (line 71) | int size() {
method isEmpty (line 79) | bool isEmpty() {
method innerGet (line 95) | bool innerGet(K& key, V& oldValue, const bool saveOldValue) {
method get (line 103) | bool get(Node* x, K& key) {
method containsKey (line 119) | bool containsKey(const K& key) {
method innerPut (line 137) | bool innerPut(const K& key, const V& value) {
method Node (line 145) | Node* put(Node* h, const K& key, const V& val, bool& ret) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMin (line 170) | void deleteMin() {
method Node (line 181) | Node* deleteMin(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMax (line 195) | void deleteMax() {
method Node (line 208) | Node* deleteMax(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method innerRemove (line 229) | void innerRemove(const K& key) {
method Node (line 238) | Node* deleteKey(Node* h, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 274) | Node* rotateRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 287) | Node* rotateLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method flipColors (line 300) | void flipColors(Node* h) {
method Node (line 312) | Node* moveRedLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 327) | Node* moveRedRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 339) | Node* balance(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method height (line 359) | int height() {
method height (line 362) | int height(Node* x) {
method K (line 376) | K* min() {
method Node (line 382) | Node* min(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 393) | K* max() {
method Node (line 399) | Node* max(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 413) | K* floor(const K& key) {
method Node (line 422) | Node* floor(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 438) | K* ceiling(const K& key) {
method Node (line 447) | Node* ceiling(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 463) | K* select(int k) {
method Node (line 472) | Node* select(Node* x, int k) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method rank (line 487) | int rank(const K& key) {
method rank (line 493) | int rank(const K& key, Node* x) {
method size (line 515) | int size(const K& lo, const K& hi) {
method check (line 528) | bool check() {
method isBST (line 539) | bool isBST() {
method isBST (line 546) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 555) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 556) | bool isSizeConsistent(Node* x) {
method is23 (line 575) | bool is23() { return is23(root); }
method is23 (line 576) | bool is23(Node* x) {
method isBalanced (line 585) | bool isBalanced() {
method isBalanced (line 596) | bool isBalanced(Node* x, int black) {
method add (line 605) | bool add(const K& key, const int tid=0) {
method remove (line 614) | bool remove(K& key, const int tid=0) {
method contains (line 624) | bool contains(K& key, const int tid=0) {
method addAll (line 635) | void addAll(K** keys, int size, const int tid=0) {
method className (line 639) | static std::string className() { return estm::ESTM::className() + "-Re...
FILE: datastructures/treemaps/HazardEras.hpp
class HazardEras (line 56) | class HazardEras {
method HazardEras (line 74) | HazardEras(int maxHEs=MAX_HES, int maxThreads=HE_MAX_THREADS) : maxHEs...
method getEra (line 97) | inline uint64_t getEra() {
method clear (line 105) | inline void clear(const int tid) {
method T (line 115) | inline T* get_protected(int index, const std::atomic<T*>& atom, const ...
method protectEraRelease (line 126) | inline void protectEraRelease(int index, int other, const int tid) {
method T (line 139) | inline T* protectPtr(int index, const std::atomic<T*>& atom, uint64_t&...
method retire (line 157) | void retire(T* ptr, const int mytid) {
method canDelete (line 175) | bool canDelete(T* obj, const int mytid) {
FILE: datastructures/treemaps/NatarajanTreeHE.hpp
class NatarajanTreeHE (line 37) | class NatarajanTreeHE {
type Node (line 41) | struct Node {
method Node (line 49) | Node(uint64_t newEra) : newEra{newEra} {}
method Node (line 50) | Node(uint64_t newEra, K k, V v, Node* l, Node* r,int lev):level(lev)...
method Node (line 51) | Node(uint64_t newEra, K k, V v, Node* l, Node* r):level(-1),key(k),v...
type SeekRecord (line 53) | struct SeekRecord{
method Node (line 72) | inline Node* getPtr(Node* mptr){
method Node (line 49) | Node(uint64_t newEra) : newEra{newEra} {}
method Node (line 50) | Node(uint64_t newEra, K k, V v, Node* l, Node* r,int lev):level(lev)...
method Node (line 51) | Node(uint64_t newEra, K k, V v, Node* l, Node* r):level(-1),key(k),v...
method getFlg (line 75) | inline bool getFlg(Node* mptr){
method getTg (line 78) | inline bool getTg(Node* mptr){
method Node (line 81) | inline Node* mixPtrFlgTg(Node* ptr, bool flg, bool tg){
method Node (line 49) | Node(uint64_t newEra) : newEra{newEra} {}
method Node (line 50) | Node(uint64_t newEra, K k, V v, Node* l, Node* r,int lev):level(lev)...
method Node (line 51) | Node(uint64_t newEra, K k, V v, Node* l, Node* r):level(-1),key(k),v...
method isInf (line 85) | inline bool isInf(Node* n){
method getInfLevel (line 88) | inline int getInfLevel(Node* n){
method nodeLess (line 93) | inline bool nodeLess(Node* n1, Node* n2){
method nodeEqual (line 100) | inline bool nodeEqual(Node* n1, Node* n2){
method nodeLessEqual (line 110) | inline bool nodeLessEqual(Node* n1, Node* n2){
method NatarajanTreeHE (line 119) | NatarajanTreeHE(const int maxThreads=0) {
method className (line 130) | static std::string className() { return "NatarajanTreeHE"; }
FILE: datastructures/treemaps/OFLFRedBlackTree.hpp
class OFLFRedBlackTree (line 12) | class OFLFRedBlackTree {
type Node (line 16) | struct Node : public oflf::tmbase {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method assignAndFreeIfNull (line 28) | inline void assignAndFreeIfNull(oflf::tmtype<Node*>& z, Node* w) {
method OFLFRedBlackTree (line 38) | OFLFRedBlackTree(int numThreads=0){ }
method isRed (line 53) | bool isRed(Node* x) {
method size (line 59) | int size(Node* x) {
method size (line 69) | int size() {
method isEmpty (line 77) | bool isEmpty() {
method innerGet (line 93) | bool innerGet(K& key, V& oldValue, const bool saveOldValue) {
method get (line 101) | bool get(Node* x, K& key) {
method containsKey (line 117) | bool containsKey(const K& key) {
method innerPut (line 135) | bool innerPut(const K& key, const V& value) {
method Node (line 143) | Node* put(Node* h, const K& key, const V& val, bool& ret) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMin (line 168) | void deleteMin() {
method Node (line 179) | Node* deleteMin(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMax (line 193) | void deleteMax() {
method Node (line 206) | Node* deleteMax(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method innerRemove (line 227) | void innerRemove(const K& key) {
method Node (line 236) | Node* deleteKey(Node* h, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 272) | Node* rotateRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 285) | Node* rotateLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method flipColors (line 298) | void flipColors(Node* h) {
method Node (line 310) | Node* moveRedLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 325) | Node* moveRedRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 337) | Node* balance(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method height (line 357) | int height() {
method height (line 360) | int height(Node* x) {
method K (line 374) | K* min() {
method Node (line 380) | Node* min(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 391) | K* max() {
method Node (line 397) | Node* max(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 411) | K* floor(const K& key) {
method Node (line 420) | Node* floor(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 436) | K* ceiling(const K& key) {
method Node (line 445) | Node* ceiling(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 461) | K* select(int k) {
method Node (line 470) | Node* select(Node* x, int k) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method rank (line 485) | int rank(const K& key) {
method rank (line 491) | int rank(const K& key, Node* x) {
method size (line 513) | int size(const K& lo, const K& hi) {
method check (line 526) | bool check() {
method isBST (line 537) | bool isBST() {
method isBST (line 544) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 553) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 554) | bool isSizeConsistent(Node* x) {
method is23 (line 573) | bool is23() { return is23(root); }
method is23 (line 574) | bool is23(Node* x) {
method isBalanced (line 583) | bool isBalanced() {
method isBalanced (line 594) | bool isBalanced(Node* x, int black) {
method add (line 603) | bool add(K key, const int tid=0) {
method remove (line 610) | bool remove(K key, const int tid=0) {
method contains (line 619) | bool contains(K key, const int tid=0) {
method addAll (line 628) | void addAll(K** keys, int size, const int tid=0) {
method className (line 632) | static std::string className() { return "OF-LF-RedBlackTree"; }
FILE: datastructures/treemaps/OFWFRedBlackTree.hpp
class OFWFRedBlackTree (line 12) | class OFWFRedBlackTree {
type Node (line 16) | struct Node : public ofwf::tmbase {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method assignAndFreeIfNull (line 28) | inline void assignAndFreeIfNull(ofwf::tmtype<Node*>& z, Node* w) {
method OFWFRedBlackTree (line 38) | OFWFRedBlackTree(int numThreads=0){ }
method isRed (line 53) | bool isRed(Node* x) {
method size (line 59) | int size(Node* x) {
method size (line 69) | int size() {
method isEmpty (line 77) | bool isEmpty() {
method innerGet (line 93) | bool innerGet(K key, V& oldValue, const bool saveOldValue) {
method get (line 101) | bool get(Node* x, K& key) {
method containsKey (line 117) | bool containsKey(const K& key) {
method innerPut (line 135) | bool innerPut(const K& key, const V& value) {
method Node (line 143) | Node* put(Node* h, const K& key, const V& val, bool& ret) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMin (line 168) | void deleteMin() {
method Node (line 179) | Node* deleteMin(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMax (line 193) | void deleteMax() {
method Node (line 206) | Node* deleteMax(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method innerRemove (line 227) | void innerRemove(K key) {
method Node (line 236) | Node* deleteKey(Node* h, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 272) | Node* rotateRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 285) | Node* rotateLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method flipColors (line 298) | void flipColors(Node* h) {
method Node (line 310) | Node* moveRedLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 325) | Node* moveRedRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 337) | Node* balance(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method height (line 357) | int height() {
method height (line 360) | int height(Node* x) {
method K (line 374) | K* min() {
method Node (line 380) | Node* min(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 391) | K* max() {
method Node (line 397) | Node* max(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 411) | K* floor(const K& key) {
method Node (line 420) | Node* floor(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 436) | K* ceiling(const K& key) {
method Node (line 445) | Node* ceiling(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 461) | K* select(int k) {
method Node (line 470) | Node* select(Node* x, int k) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method rank (line 485) | int rank(const K& key) {
method rank (line 491) | int rank(const K& key, Node* x) {
method size (line 513) | int size(const K& lo, const K& hi) {
method check (line 526) | bool check() {
method isBST (line 537) | bool isBST() {
method isBST (line 544) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 553) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 554) | bool isSizeConsistent(Node* x) {
method is23 (line 573) | bool is23() { return is23(root); }
method is23 (line 574) | bool is23(Node* x) {
method isBalanced (line 583) | bool isBalanced() {
method isBalanced (line 594) | bool isBalanced(Node* x, int black) {
method add (line 603) | bool add(K key, const int tid=0) {
method remove (line 610) | bool remove(K key, const int tid=0) {
method contains (line 619) | bool contains(K key, const int tid=0) {
method addAll (line 626) | void addAll(K** keys, int size, const int tid=0) {
method className (line 630) | static std::string className() { return "OF-WF-RedBlackTree"; }
FILE: datastructures/treemaps/TinySTMRedBlackTree.hpp
class TinySTMRedBlackTree (line 12) | class TinySTMRedBlackTree {
type Node (line 16) | struct Node {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method assignAndFreeIfNull (line 28) | inline void assignAndFreeIfNull(tinystm::tmtype<Node*>& z, Node* w) {
method TinySTMRedBlackTree (line 38) | TinySTMRedBlackTree(int maxThreads=0){ }
method isRed (line 55) | bool isRed(Node* x) {
method size (line 61) | int size(Node* x) {
method size (line 71) | int size() {
method isEmpty (line 79) | bool isEmpty() {
method innerGet (line 95) | bool innerGet(K& key, V& oldValue, const bool saveOldValue) {
method get (line 103) | bool get(Node* x, K& key) {
method containsKey (line 119) | bool containsKey(const K& key) {
method innerPut (line 137) | bool innerPut(const K& key, const V& value) {
method Node (line 145) | Node* put(Node* h, const K& key, const V& val, bool& ret) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMin (line 170) | void deleteMin() {
method Node (line 181) | Node* deleteMin(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method deleteMax (line 195) | void deleteMax() {
method Node (line 208) | Node* deleteMax(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method innerRemove (line 229) | void innerRemove(const K& key) {
method Node (line 238) | Node* deleteKey(Node* h, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 274) | Node* rotateRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 287) | Node* rotateLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method flipColors (line 300) | void flipColors(Node* h) {
method Node (line 312) | Node* moveRedLeft(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 327) | Node* moveRedRight(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 339) | Node* balance(Node* h) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method height (line 359) | int height() {
method height (line 362) | int height(Node* x) {
method K (line 376) | K* min() {
method Node (line 382) | Node* min(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 393) | K* max() {
method Node (line 399) | Node* max(Node* x) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 413) | K* floor(const K& key) {
method Node (line 422) | Node* floor(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 438) | K* ceiling(const K& key) {
method Node (line 447) | Node* ceiling(Node* x, const K& key) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method K (line 463) | K* select(int k) {
method Node (line 472) | Node* select(Node* x, int k) {
method Node (line 23) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method rank (line 487) | int rank(const K& key) {
method rank (line 493) | int rank(const K& key, Node* x) {
method size (line 515) | int size(const K& lo, const K& hi) {
method check (line 528) | bool check() {
method isBST (line 539) | bool isBST() {
method isBST (line 546) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 555) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 556) | bool isSizeConsistent(Node* x) {
method is23 (line 575) | bool is23() { return is23(root); }
method is23 (line 576) | bool is23(Node* x) {
method isBalanced (line 585) | bool isBalanced() {
method isBalanced (line 596) | bool isBalanced(Node* x, int black) {
method add (line 605) | bool add(K key, const int tid=0) {
method remove (line 612) | bool remove(K key, const int tid=0) {
method contains (line 621) | bool contains(K key, const int tid=0) {
method addAll (line 630) | void addAll(K** keys, int size, const int tid=0) {
method className (line 634) | static std::string className() { return tinystm::TinySTM::className() ...
FILE: datastructures/trevor_brown_abtree/TrevorBrownABTree.hpp
class TrevorBrownABTree (line 16) | class TrevorBrownABTree {
method TrevorBrownABTree (line 26) | TrevorBrownABTree(int numThreads) {
method add (line 36) | bool add(K key, const int tid=0) {
method remove (line 46) | bool remove(K key, const int tid=0) {
method contains (line 55) | bool contains(K key, const int tid=0) {
method addAll (line 66) | void addAll(K** keys, int size, const int tid=0) {
method className (line 70) | static std::string className() { return "TrevorBrown-AB-Tree"; }
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/generalize-small.h
function AO_char_load_acquire (line 24) | AO_INLINE unsigned char
function AO_char_load_read (line 38) | AO_INLINE unsigned char
function AO_INLINE (line 141) | AO_INLINE AO_t
function AO_INLINE (line 158) | AO_INLINE AO_t
function AO_INLINE (line 175) | AO_INLINE AO_t
function AO_short_load_acquire (line 599) | AO_INLINE unsigned short
function AO_short_load_read (line 613) | AO_INLINE unsigned short
function AO_INLINE (line 716) | AO_INLINE AO_t
function AO_INLINE (line 733) | AO_INLINE AO_t
function AO_INLINE (line 750) | AO_INLINE AO_t
function AO_int_load_acquire (line 1174) | AO_INLINE unsigned int
function AO_int_load_read (line 1188) | AO_INLINE unsigned int
function AO_INLINE (line 1291) | AO_INLINE AO_t
function AO_INLINE (line 1308) | AO_INLINE AO_t
function AO_INLINE (line 1325) | AO_INLINE AO_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/generalize.h
function AO_INLINE (line 80) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 93) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 106) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 119) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 132) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 146) | AO_INLINE void AO_nop(void) {}
function AO_INLINE (line 151) | AO_INLINE void
function AO_INLINE (line 200) | AO_INLINE AO_t
function AO_INLINE (line 214) | AO_INLINE AO_t
function AO_INLINE (line 317) | AO_INLINE AO_TS_t
function AO_INLINE (line 334) | AO_INLINE AO_t
function AO_INLINE (line 350) | AO_INLINE AO_t
function AO_INLINE (line 366) | AO_INLINE AO_t
function AO_INLINE (line 382) | AO_INLINE AO_t
function AO_INLINE (line 778) | AO_INLINE void
function AO_INLINE (line 972) | AO_INLINE int
function AO_INLINE (line 1087) | AO_INLINE int
function AO_INLINE (line 1203) | AO_INLINE int
function AO_INLINE (line 1320) | AO_INLINE int
function AO_INLINE (line 1333) | AO_INLINE int
function AO_INLINE (line 1346) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/acquire_release_volatile.h
function AO_INLINE (line 45) | AO_INLINE AO_t
function AO_INLINE (line 55) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/aligned_atomic_load_store.h
function AO_INLINE (line 28) | AO_INLINE AO_t
function AO_INLINE (line 39) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/armcc/arm_v6.h
function AO_INLINE (line 43) | AO_INLINE void
function AO_INLINE (line 56) | AO_INLINE AO_t
function double_ptr_storage (line 205) | double_ptr_storage load_ex(volatile AO_double_t *addr) {
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/atomic_load_store.h
function AO_INLINE (line 28) | AO_INLINE AO_t
function AO_INLINE (line 38) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/char_acquire_release_volatile.h
function AO_char_load_acquire (line 36) | AO_INLINE unsigned char
function AO_INLINE (line 46) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/char_atomic_load_store.h
function AO_char_load (line 28) | AO_INLINE unsigned char
function AO_INLINE (line 38) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/alpha.h
function AO_INLINE (line 25) | AO_INLINE void
function AO_INLINE (line 33) | AO_INLINE void
function AO_INLINE (line 45) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/arm.h
function AO_INLINE (line 43) | AO_INLINE void
function AO_INLINE (line 57) | AO_INLINE AO_t
function AO_INLINE (line 91) | AO_INLINE void AO_store(volatile AO_t *addr, AO_t value)
function AO_INLINE (line 118) | AO_INLINE AO_TS_t
function AO_INLINE (line 140) | AO_INLINE AO_t
function AO_INLINE (line 162) | AO_INLINE AO_t
function AO_INLINE (line 184) | AO_INLINE AO_t
function AO_INLINE (line 207) | AO_INLINE int
function AO_INLINE (line 229) | AO_INLINE int
function AO_INLINE (line 267) | AO_INLINE AO_TS_VAL_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/avr32.h
function AO_INLINE (line 31) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 46) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/cris.h
function AO_INLINE (line 50) | AO_INLINE AO_TS_VAL_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/hppa.h
type AO_pa_clearable_loc (line 38) | struct AO_pa_clearable_loc {
type AO_PA_TS_val (line 47) | typedef enum {AO_PA_TS_set = 0, AO_PA_TS_clear = 1} AO_PA_TS_val;
function AO_INLINE (line 80) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 87) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/ia64.h
function AO_INLINE (line 57) | AO_INLINE void
function AO_INLINE (line 64) | AO_INLINE AO_t
function AO_INLINE (line 76) | AO_INLINE AO_t
function AO_INLINE (line 89) | AO_INLINE AO_t
function AO_INLINE (line 102) | AO_INLINE AO_t
function AO_int_fetch_and_add1_acquire (line 117) | AO_INLINE unsigned int
function AO_int_fetch_and_add1_release (line 128) | AO_INLINE unsigned int
function AO_int_fetch_and_sub1_acquire (line 140) | AO_INLINE unsigned int
function AO_int_fetch_and_sub1_release (line 152) | AO_INLINE unsigned int
function AO_INLINE (line 166) | AO_INLINE int
function AO_INLINE (line 183) | AO_INLINE int
function AO_INLINE (line 200) | AO_INLINE int
function AO_INLINE (line 215) | AO_INLINE int
function AO_INLINE (line 230) | AO_INLINE int
function AO_INLINE (line 245) | AO_INLINE int
function AO_INLINE (line 262) | AO_INLINE int
function AO_INLINE (line 275) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/m68k.h
type AO_t (line 21) | typedef unsigned long AO_t __attribute__ ((aligned (4)));
function AO_INLINE (line 33) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 52) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/mips.h
function AO_INLINE (line 29) | AO_INLINE void
function AO_INLINE (line 44) | AO_INLINE int
function AO_INLINE (line 74) | AO_INLINE int
function AO_INLINE (line 83) | AO_INLINE int
function AO_INLINE (line 91) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/powerpc.h
function AO_INLINE (line 39) | AO_INLINE void
function AO_INLINE (line 48) | AO_INLINE void
function AO_INLINE (line 72) | AO_INLINE AO_t
function AO_INLINE (line 87) | AO_INLINE AO_t
function AO_INLINE (line 109) | AO_INLINE void
function AO_INLINE (line 123) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 144) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 167) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 176) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 184) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 197) | AO_INLINE int
function AO_INLINE (line 219) | AO_INLINE int
function AO_INLINE (line 242) | AO_INLINE int
function AO_INLINE (line 251) | AO_INLINE int
function AO_INLINE (line 259) | AO_INLINE int
function AO_INLINE (line 273) | AO_INLINE AO_t
function AO_INLINE (line 294) | AO_INLINE AO_t
function AO_INLINE (line 315) | AO_INLINE AO_t
function AO_INLINE (line 324) | AO_INLINE AO_t
function AO_INLINE (line 332) | AO_INLINE AO_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/s390.h
function AO_INLINE (line 43) | AO_INLINE AO_t AO_compare_and_swap_full(volatile AO_t *addr,
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/sh.h
function AO_INLINE (line 21) | AO_INLINE AO_TS_VAL_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/sparc.h
function AO_INLINE (line 30) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 44) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/x86.h
function AO_INLINE (line 40) | AO_INLINE void
function AO_INLINE (line 60) | AO_INLINE AO_t
function AO_char_fetch_and_add_full (line 73) | AO_INLINE unsigned char
function AO_short_fetch_and_add_full (line 86) | AO_INLINE unsigned short
function AO_INLINE (line 100) | AO_INLINE void
function AO_INLINE (line 109) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 123) | AO_INLINE int
function AO_INLINE (line 141) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/x86_64.h
function AO_INLINE (line 34) | AO_INLINE void
function AO_INLINE (line 46) | AO_INLINE AO_t
function AO_char_fetch_and_add_full (line 59) | AO_INLINE unsigned char
function AO_short_fetch_and_add_full (line 72) | AO_INLINE unsigned short
function AO_int_fetch_and_add_full (line 85) | AO_INLINE unsigned int
function AO_INLINE (line 98) | AO_INLINE void
function AO_INLINE (line 107) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 121) | AO_INLINE int
function AO_INLINE (line 147) | AO_INLINE int
function AO_INLINE (line 170) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/generic_pthread.h
function AO_INLINE (line 40) | AO_INLINE void
function AO_INLINE (line 49) | AO_INLINE AO_t
function AO_INLINE (line 61) | AO_INLINE void
function AO_char_load_full (line 71) | AO_INLINE unsigned char
function AO_INLINE (line 83) | AO_INLINE void
function AO_short_load_full (line 93) | AO_INLINE unsigned short
function AO_INLINE (line 105) | AO_INLINE void
function AO_int_load_full (line 115) | AO_INLINE unsigned int
function AO_INLINE (line 127) | AO_INLINE void
function AO_INLINE (line 137) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 151) | AO_INLINE AO_t
function AO_char_fetch_and_add_full (line 165) | AO_INLINE unsigned char
function AO_short_fetch_and_add_full (line 179) | AO_INLINE unsigned short
function AO_int_fetch_and_add_full (line 193) | AO_INLINE unsigned int
function AO_INLINE (line 207) | AO_INLINE void
function AO_INLINE (line 220) | AO_INLINE int
type AO_double_t (line 240) | typedef struct {
function AO_INLINE (line 247) | AO_INLINE int
function AO_INLINE (line 267) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/hpc/hppa.h
type AO_pa_clearable_loc (line 43) | struct AO_pa_clearable_loc {
type AO_PA_TS_val (line 52) | typedef enum {AO_PA_TS_set = 0, AO_PA_TS_clear = 1} AO_PA_TS_val;
function AO_INLINE (line 81) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 91) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/hpc/ia64.h
function AO_INLINE (line 45) | AO_INLINE void
function AO_INLINE (line 52) | AO_INLINE AO_t
function AO_INLINE (line 60) | AO_INLINE AO_t
function AO_INLINE (line 69) | AO_INLINE AO_t
function AO_INLINE (line 78) | AO_INLINE AO_t
function AO_INLINE (line 87) | AO_INLINE int
function AO_INLINE (line 101) | AO_INLINE int
function AO_INLINE (line 115) | AO_INLINE int
function AO_INLINE (line 129) | AO_INLINE int
function AO_INLINE (line 143) | AO_INLINE int
function AO_INLINE (line 157) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ibmc/powerpc.h
function AO_INLINE (line 37) | AO_INLINE AO_t
function AO_INLINE (line 47) | AO_INLINE void
function AO_INLINE (line 66) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 75) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 83) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 101) | AO_INLINE AO_t
function AO_INLINE (line 110) | AO_INLINE AO_t
function AO_INLINE (line 118) | AO_INLINE AO_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/icc/ia64.h
function AO_INLINE (line 41) | AO_INLINE AO_t
function AO_INLINE (line 48) | AO_INLINE void
function AO_char_load_acquire (line 55) | AO_INLINE unsigned char
function AO_INLINE (line 63) | AO_INLINE void
function AO_short_load_acquire (line 70) | AO_INLINE unsigned short
function AO_INLINE (line 78) | AO_INLINE void
function AO_int_load_acquire (line 85) | AO_INLINE unsigned int
function AO_INLINE (line 93) | AO_INLINE void
function AO_INLINE (line 100) | AO_INLINE void
function AO_INLINE (line 107) | AO_INLINE AO_t
function AO_INLINE (line 114) | AO_INLINE AO_t
function AO_INLINE (line 122) | AO_INLINE AO_t
function AO_INLINE (line 130) | AO_INLINE AO_t
function AO_INLINE (line 138) | AO_INLINE int
function AO_INLINE (line 149) | AO_INLINE int
function AO_INLINE (line 160) | AO_INLINE int
function AO_INLINE (line 171) | AO_INLINE int
function AO_INLINE (line 182) | AO_INLINE int
function AO_INLINE (line 193) | AO_INLINE int
function AO_INLINE (line 204) | AO_INLINE int
function AO_INLINE (line 215) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/int_acquire_release_volatile.h
function AO_int_load_acquire (line 36) | AO_INLINE unsigned int
function AO_INLINE (line 46) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/int_aligned_atomic_load_store.h
function AO_int_load (line 28) | AO_INLINE unsigned int
function AO_INLINE (line 39) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/int_atomic_load_store.h
function AO_int_load (line 28) | AO_INLINE unsigned int
function AO_INLINE (line 38) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/arm.h
function AO_INLINE (line 41) | AO_INLINE void AO_nop_full(void) {}
function AO_INLINE (line 50) | AO_INLINE AO_t
function AO_INLINE (line 58) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/common32_defs.h
function AO_INLINE (line 80) | AO_INLINE AO_t
function AO_INLINE (line 89) | AO_INLINE AO_t
function AO_INLINE (line 97) | AO_INLINE AO_t
function AO_INLINE (line 107) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/x86.h
function AO_INLINE (line 55) | AO_INLINE void
function AO_INLINE (line 71) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 96) | AO_INLINE int
function AO_INLINE (line 109) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/x86_64.h
function AO_INLINE (line 57) | AO_INLINE AO_t
function AO_INLINE (line 65) | AO_INLINE AO_t
function AO_INLINE (line 73) | AO_INLINE AO_t
function AO_INLINE (line 81) | AO_INLINE int
function AO_INLINE (line 97) | AO_INLINE void
function AO_INLINE (line 106) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 131) | AO_INLINE int
function AO_INLINE (line 151) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ordered.h
function AO_INLINE (line 30) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ordered_except_wr.h
function AO_INLINE (line 32) | AO_INLINE void
function AO_INLINE (line 44) | AO_INLINE void
function AO_INLINE (line 59) | AO_INLINE void
function AO_INLINE (line 74) | AO_INLINE void
function AO_INLINE (line 89) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/read_ordered.h
function AO_INLINE (line 30) | AO_INLINE void
function AO_INLINE (line 40) | AO_INLINE AO_t
function AO_INLINE (line 56) | AO_INLINE AO_t
function AO_INLINE (line 72) | AO_INLINE AO_t
function AO_INLINE (line 88) | AO_INLINE AO_t
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/short_acquire_release_volatile.h
function AO_short_load_acquire (line 36) | AO_INLINE unsigned short
function AO_INLINE (line 46) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/short_aligned_atomic_load_store.h
function AO_short_load (line 28) | AO_INLINE unsigned short
function AO_INLINE (line 39) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/short_atomic_load_store.h
function AO_short_load (line 28) | AO_INLINE unsigned short
function AO_INLINE (line 38) | AO_INLINE void
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/standard_ao_double_t.h
type __m128 (line 9) | typedef __m128 double_ptr_storage;
type double_ptr_storage (line 11) | typedef unsigned __int64 double_ptr_storage;
type double_ptr_storage (line 13) | typedef unsigned long long double_ptr_storage;
type AO_double_t (line 18) | typedef union {
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/sunc/x86.h
function AO_INLINE (line 37) | AO_INLINE void
function AO_INLINE (line 57) | AO_INLINE AO_t
function AO_char_fetch_and_add_full (line 70) | AO_INLINE unsigned char
function AO_short_fetch_and_add_full (line 83) | AO_INLINE unsigned short
function AO_INLINE (line 97) | AO_INLINE void
function AO_INLINE (line 107) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 122) | AO_INLINE int
function AO_INLINE (line 140) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/sunc/x86_64.h
function AO_INLINE (line 34) | AO_INLINE void
function AO_INLINE (line 46) | AO_INLINE AO_t
function AO_char_fetch_and_add_full (line 59) | AO_INLINE unsigned char
function AO_short_fetch_and_add_full (line 72) | AO_INLINE unsigned short
function AO_int_fetch_and_add_full (line 85) | AO_INLINE unsigned int
function AO_INLINE (line 98) | AO_INLINE void
function AO_INLINE (line 108) | AO_INLINE AO_TS_VAL_t
function AO_INLINE (line 123) | AO_INLINE int
function AO_INLINE (line 146) | AO_INLINE int
function AO_INLINE (line 169) | AO_INLINE int
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h
type AO_TS_val (line 29) | typedef enum {AO_TS_clear = 0, AO_TS_set = 1} AO_TS_val;
FILE: datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/test_and_set_t_is_char.h
type AO_BYTE_TS_val (line 30) | typedef enum {AO_BYTE_TS_clear = 0, AO_BYTE_TS_set = 0xff} AO_BYTE_TS_val;
FILE: datastructures/trevor_brown_abtree/common/dcss/dcss_plus.h
type dcsspresult_t (line 33) | struct dcsspresult_t {
FILE: datastructures/trevor_brown_abtree/common/dcss/dcss_plus_impl.h
function isDcssp (line 22) | static bool isDcssp(casword_t val) {
function NUM_PROCESSES (line 195) | NUM_PROCESSES(numProcesses) {
FILE: datastructures/trevor_brown_abtree/common/dcss/testing.cpp
function validate1 (line 64) | bool validate1() {
function validate2 (line 114) | bool validate2() {
function main (line 138) | int main(int argc, char** argv) {
FILE: datastructures/trevor_brown_abtree/common/descriptors/descriptors.h
type tagptr_t (line 11) | typedef intptr_t tagptr_t;
type mutables_t (line 12) | typedef intptr_t mutables_t;
FILE: datastructures/trevor_brown_abtree/common/recordmgr/allocator_bump.h
function T (line 30) | T* bump_memory_next(const int tid) {
function bump_memory_bytes_remaining (line 35) | int bump_memory_bytes_remaining(const int tid) {
function bump_memory_full (line 38) | bool bump_memory_full(const int tid) {
function bump_memory_allocate (line 42) | void bump_memory_allocate(const int tid) {
type allocator_bump (line 65) | typedef allocator_bump<_Tp1> other;
function T (line 69) | T* allocate(const int tid) {
function deallocate (line 89) | void static deallocate(const int tid, T * const p) {
function deallocateAndClear (line 94) | void deallocateAndClear(const int tid, blockbag<T> * const bag) {
function debugPrintStatus (line 101) | void debugPrintStatus(const int tid) {}
function initThread (line 103) | void initThread(const int tid) {}
FILE: datastructures/trevor_brown_abtree/common/recordmgr/allocator_interface.h
type allocator_interface (line 25) | typedef allocator_interface<_Tp1> other;
FILE: datastructures/trevor_brown_abtree/common/recordmgr/allocator_new.h
function T (line 30) | T* allocate(const int tid) {
function deallocate (line 46) | void deallocate(const int tid, T * const p) {
function deallocateAndClear (line 59) | void deallocateAndClear(const int tid, blockbag<T> * const bag) {
function debugPrintStatus (line 70) | void debugPrintStatus(const int tid) {
function initThread (line 77) | void initThread(const int tid) {}
FILE: datastructures/trevor_brown_abtree/common/recordmgr/allocator_new_segregated.h
type allocator_new_segregated (line 32) | typedef allocator_new_segregated<_Tp1> other;
function T (line 36) | T* allocate(const int tid) {
function deallocate (line 52) | void deallocate(const int tid, T * const p) {
function deallocateAndClear (line 66) | void deallocateAndClear(const int tid, blockbag<T> * const bag) {
function debugPrintStatus (line 77) | void debugPrintStatus(const int tid) {}
function initThread (line 79) | void initThread(const int tid) {}
FILE: datastructures/trevor_brown_abtree/common/recordmgr/allocator_once.h
function T (line 37) | T* bump_memory_next(const int tid) {
function bump_memory_bytes_remaining (line 42) | int bump_memory_bytes_remaining(const int tid) {
function bump_memory_full (line 45) | bool bump_memory_full(const int tid) {
type allocator_once (line 52) | typedef allocator_once<_Tp1> other;
function T (line 56) | T* allocate(const int tid) {
function deallocate (line 60) | void static deallocate(const int tid, T * const p) {
function deallocateAndClear (line 65) | void deallocateAndClear(const int tid, blockbag<T> * const bag) {
function debugPrintStatus (line 72) | void debugPrintStatus(const int tid) {}
function initThread (line 74) | void initThread(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/arraylist.h
function capacity (line 27) | AtomicArrayList(const int _capacity) : capacity(_capacity) {
function T (line 35) | inline T* get(const int ix) {
function size (line 38) | inline int size() {
function add (line 41) | inline void add(T * const obj) {
function erase (line 49) | inline void erase(const int ix) {
function erase (line 55) | inline void erase(T * const obj) {
function getIndex (line 59) | inline int getIndex(T * const obj) {
function contains (line 66) | inline bool contains(T * const obj) {
function clear (line 69) | inline void clear() {
function isFull (line 74) | inline bool isFull() {
function isEmpty (line 77) | inline bool isEmpty() {
function capacity (line 89) | ArrayList(const int _capacity) : capacity(_capacity) {
function T (line 96) | inline T* get(const int ix) {
function size (line 99) | inline int size() {
function add (line 102) | inline void add(T * const obj) {
function erase (line 106) | inline void erase(const int ix) {
function erase (line 110) | inline void erase(T * const obj) {
function getIndex (line 114) | inline int getIndex(T * const obj) {
function contains (line 120) | inline bool contains(T * const obj) {
function clear (line 123) | inline void clear() {
function isFull (line 126) | inline bool isFull() {
function isEmpty (line 129) | inline bool isEmpty() {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/blockbag.h
function next (line 39) | next(_next) {
function isFull (line 46) | bool isFull() {
function isEmpty (line 49) | bool isEmpty() {
function push (line 53) | void push(T * const obj) {
function T (line 62) | T* pop() {
function T (line 68) | T* peek(const int ix) {
function contains (line 74) | bool contains(T* const obj) {
function erase (line 82) | void erase(T* const obj) {
function erase (line 100) | void erase(const int ix) {
function replace (line 110) | void replace(const int ix, T* const obj) {
function computeSize (line 116) | int computeSize() {
function clearWithoutFreeingElements (line 125) | void clearWithoutFreeingElements() {
function T (line 175) | inline T* operator*() const {
function swap (line 225) | void swap(block<T> * const otherCurr, const int otherIx) {
function erase (line 231) | void erase() {
function validate (line 272) | void validate() {
function debugPrintBag (line 291) | void debugPrintBag() {
function computeSizeInBlocks (line 299) | int computeSizeInBlocks() {
function getOwner (line 336) | int getOwner() {
function incrementReclaimCount (line 340) | inline void incrementReclaimCount() {
function getReclaimCount (line 345) | inline long long getReclaimCount() {
function add (line 357) | void add(T * const obj) {
function isEmpty (line 400) | bool isEmpty() {
function erase (line 406) | bool erase(block<T> * const curr, const int ix) {
function T (line 443) | T* remove() {
function DEBUG2 (line 553) | DEBUG2 if (sizeInBlocks != computeSizeInBlocks()) { std::cout<<"sizeInBl...
function addFullBlock (line 558) | void addFullBlock(block<T> *b) {
function appendMoveFullBlocks (line 613) | void appendMoveFullBlocks(blockbag<T> * const other, block<T> * predeces...
function appendMoveFullBlocks (line 639) | void appendMoveFullBlocks(blockbag<T> * const other) {
function appendMoveAll (line 642) | void appendMoveAll(blockbag<T> * const other) {
function computeSize (line 652) | int computeSize() {
function getSizeInBlocks (line 661) | int getSizeInBlocks() {
function clearWithoutFreeingElements (line 670) | void clearWithoutFreeingElements() {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/blockpool.h
function deallocateBlock (line 66) | void deallocateBlock(block<T> * const b) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/debug_info.h
type _memrecl_counters (line 13) | struct _memrecl_counters {
function class (line 25) | class debugInfo {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/debugcounter.h
function class (line 16) | class debugCounter {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/globals.h
type CallbackReturn (line 34) | typedef bool CallbackReturn;
type CallbackReturn (line 36) | typedef CallbackReturn (*CallbackType)(CallbackArg);
FILE: datastructures/trevor_brown_abtree/common/recordmgr/hashtable.h
function namespace (line 17) | namespace hashset_namespace {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/lockfreeblockbag.h
type tagged_ptr (line 33) | struct tagged_ptr {
function addBlock (line 72) | void addBlock(block<T> *b) {
function sizeInBlocks (line 84) | int sizeInBlocks() {
function size (line 94) | long long size() {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/pool_interface.h
type pool_interface (line 29) | typedef pool_interface<_Tp1, Alloc> other;
type pool_interface (line 33) | typedef pool_interface<_Tp1, _Tp2> other;
function string (line 36) | string getSizeString() { return ""; }
FILE: datastructures/trevor_brown_abtree/common/recordmgr/pool_none.h
type pool_none (line 24) | typedef pool_none<_Tp1, Alloc> other;
type pool_none (line 28) | typedef pool_none<_Tp1, _Tp2> other;
function string (line 31) | string getSizeString() { return "no pool"; }
function T (line 37) | inline T* get(const int tid) {
function add (line 41) | inline void add(const int tid, T* ptr) {
function addMoveFullBlocks (line 44) | inline void addMoveFullBlocks(const int tid, blockbag<T> *bag, block<T> ...
function addMoveFullBlocks (line 48) | inline void addMoveFullBlocks(const int tid, blockbag<T> *bag) {
function addMoveAll (line 55) | inline void addMoveAll(const int tid, blockbag<T> *bag) {
function computeSize (line 62) | inline int computeSize(const int tid) {
function debugPrintStatus (line 66) | void debugPrintStatus(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/pool_perthread_and_shared.h
function tryGiveFreeObjects (line 30) | inline bool tryGiveFreeObjects(const int tid) {
type pool_perthread_and_shared (line 55) | typedef pool_perthread_and_shared<_Tp1, Alloc> other;
type pool_perthread_and_shared (line 59) | typedef pool_perthread_and_shared<_Tp1, _Tp2> other;
function string (line 70) | string getSizeString() {
function T (line 86) | inline T* get(const int tid) {
function add (line 90) | inline void add(const int tid, T* ptr) {
function addMoveFullBlocks (line 94) | inline void addMoveFullBlocks(const int tid, blockbag<T> *bag, block<T> ...
function addMoveFullBlocks (line 100) | inline void addMoveFullBlocks(const int tid, blockbag<T> *bag) {
function addMoveAll (line 106) | inline void addMoveAll(const int tid, blockbag<T> *bag) {
function computeSize (line 111) | inline int computeSize(const int tid) {
function debugPrintStatus (line 115) | void debugPrintStatus(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_debra.h
type reclaimer_debra (line 55) | typedef reclaimer_debra<_Tp1, Pool> other;
type reclaimer_debra (line 59) | typedef reclaimer_debra<_Tp1, _Tp2> other;
function getSafeBlockbags (line 111) | inline void getSafeBlockbags(const int tid, blockbag<T> ** bags) {
function getSizeInNodes (line 173) | long long getSizeInNodes() {
function string (line 182) | string getSizeString() {
function quiescenceIsPerRecordType (line 188) | inline static bool quiescenceIsPerRecordType() { return false; }
function isQuiescent (line 190) | inline bool isQuiescent(const int tid) {
function isProtected (line 194) | inline static bool isProtected(const int tid, T * const obj) {
function isQProtected (line 197) | inline static bool isQProtected(const int tid, T * const obj) {
function unprotect (line 203) | inline static void unprotect(const int tid, T * const obj) {}
function qUnprotectAll (line 207) | inline static void qUnprotectAll(const int tid) {}
function shouldHelp (line 209) | inline static bool shouldHelp() { return true; }
function rotateEpochBags (line 212) | inline void rotateEpochBags(const int tid) {
function leaveQuiescentState (line 225) | inline bool leaveQuiescentState(const int tid, void * const * const recl...
function enterQuiescentState (line 270) | inline void enterQuiescentState(const int tid) {
function retire (line 276) | inline void retire(const int tid, T* p) {
function unretireLast (line 281) | inline void unretireLast(const int tid) {
function debugPrintStatus (line 286) | void debugPrintStatus(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_debraplus.h
function neutralizeOther (line 75) | inline bool neutralizeOther(const int tid, const int otherTid, const lon...
type reclaimer_debraplus (line 131) | typedef reclaimer_debraplus<_Tp1, Pool> other;
type reclaimer_debraplus (line 135) | typedef reclaimer_debraplus<_Tp1, _Tp2> other;
function quiescenceIsPerRecordType (line 138) | inline static bool quiescenceIsPerRecordType() { return false; }
function supportsCrashRecovery (line 139) | inline static bool supportsCrashRecovery() { return true; }
function isQuiescent (line 140) | inline bool isQuiescent(const int tid) {
function isProtected (line 145) | inline static bool isProtected(const int tid, T * const obj) {
function unprotect (line 152) | inline static void unprotect(const int tid, T * const obj) {}
function isQProtected (line 154) | inline bool isQProtected(const int tid, T * const obj) {
function qUnprotectAll (line 182) | inline void qUnprotectAll(const int tid) {
function rotateEpochBags (line 190) | inline void rotateEpochBags(const int tid) {
function leaveQuiescentState (line 252) | inline bool leaveQuiescentState(const int tid, void * const * const recl...
function enterQuiescentState (line 306) | inline void enterQuiescentState(const int tid) {
function retire (line 313) | inline void retire(const int tid, T* p) {
function debugPrintStatus (line 319) | void debugPrintStatus(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_hazardptr.h
type reclaimer_hazardptr (line 45) | typedef reclaimer_hazardptr<_Tp1, Pool> other;
type reclaimer_hazardptr (line 49) | typedef reclaimer_hazardptr<_Tp1, _Tp2> other;
function shouldHelp (line 52) | inline static bool shouldHelp() {
function isProtected (line 56) | bool isProtected(const int tid, T * const obj) {
function isQProtected (line 59) | bool static isQProtected(const int tid, T * const obj) {
function isQuiescent (line 62) | inline static bool isQuiescent(const int tid) {
function unprotect (line 92) | inline void unprotect(const int tid, T * const obj) {
function qUnprotectAll (line 106) | inline void qUnprotectAll(const int tid) {
function enterQuiescentState (line 111) | inline void enterQuiescentState(const int tid) {
function leaveQuiescentState (line 121) | inline static bool leaveQuiescentState(const int tid, void * const * con...
function rotateEpochBags (line 126) | inline static void rotateEpochBags(const int tid) {}
function string (line 128) | string debugPointerOutput(T* p) {
function retire (line 142) | inline void retire(const int tid, T* p) {
function debugPrintStatus (line 237) | void debugPrintStatus(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_interface.h
type reclaimer_interface (line 37) | typedef reclaimer_interface<_Tp1, Pool> other;
type reclaimer_interface (line 41) | typedef reclaimer_interface<_Tp1, _Tp2> other;
function getSizeInNodes (line 44) | long long getSizeInNodes() { return 0; }
function string (line 45) | string getSizeString() { return ""; }
function quiescenceIsPerRecordType (line 47) | inline static bool quiescenceIsPerRecordType() { return true; }
function shouldHelp (line 48) | inline static bool shouldHelp() { return true; }
function supportsCrashRecovery (line 49) | inline static bool supportsCrashRecovery() { return false; }
function isQuiescent (line 52) | inline static bool isQuiescent(const int tid) {
function unretireLast (line 78) | inline void unretireLast(const int tid) {}
function initThread (line 80) | inline void initThread(const int tid) {}
function deinitThread (line 81) | inline void deinitThread(const int tid) {}
FILE: datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_none.h
type reclaimer_none (line 23) | typedef reclaimer_none<_Tp1, Pool> other;
type reclaimer_none (line 27) | typedef reclaimer_none<_Tp1, _Tp2> other;
function string (line 30) | string getSizeString() { return "no reclaimer"; }
function shouldHelp (line 31) | inline static bool shouldHelp() {
function isQuiescent (line 35) | inline static bool isQuiescent(const int tid) {
function isProtected (line 38) | inline static bool isProtected(const int tid, T * const obj) {
function isQProtected (line 41) | inline static bool isQProtected(const int tid, T * const obj) {
function unprotect (line 49) | inline static void unprotect(const int tid, T * const obj) {}
function qUnprotectAll (line 53) | inline static void qUnprotectAll(const int tid) {}
function rotateEpochBags (line 56) | inline static void rotateEpochBags(const int tid) {
function leaveQuiescentState (line 63) | inline static bool leaveQuiescentState(const int tid, void * const * con...
function enterQuiescentState (line 66) | inline static void enterQuiescentState(const int tid) {
function retire (line 70) | inline static void retire(const int tid, T* p) {
function debugPrintStatus (line 73) | void debugPrintStatus(const int tid) {
function getSafeBlockbags (line 89) | void getSafeBlockbags(const int tid, blockbag<T> ** bags) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_rcu.h
function rcuCallback_Node (line 60) | void rcuCallback_Node(struct rcu_head *rcu) {
function rcuCallback_SCXRecord (line 71) | void rcuCallback_SCXRecord(struct rcu_head *rcu) {
function rcuCallback_kcasdesc (line 83) | void rcuCallback_kcasdesc(struct rcu_head *rcu) {
function rcuCallback_rdcssdesc (line 93) | void rcuCallback_rdcssdesc(struct rcu_head *rcu) {
type reclaimer_rcu (line 121) | typedef reclaimer_rcu<_Tp1, Pool> other;
type reclaimer_rcu (line 125) | typedef reclaimer_rcu<_Tp1, _Tp2> other;
function getSizeInNodes (line 128) | long long getSizeInNodes() {
function string (line 132) | string getSizeString() {
function quiescenceIsPerRecordType (line 138) | inline static bool quiescenceIsPerRecordType() { return false; }
function isQuiescent (line 140) | inline bool isQuiescent(const int tid) {
function isProtected (line 144) | inline static bool isProtected(const int tid, T * const obj) {
function isQProtected (line 147) | inline static bool isQProtected(const int tid, T * const obj) {
function unprotect (line 153) | inline static void unprotect(const int tid, T * const obj) {}
function qUnprotectAll (line 157) | inline static void qUnprotectAll(const int tid) {}
function shouldHelp (line 159) | inline static bool shouldHelp() { return true; }
function rotateEpochBags (line 161) | inline void rotateEpochBags(const int tid) {}
function leaveQuiescentState (line 163) | inline bool leaveQuiescentState(const int tid, void * const * const recl...
function enterQuiescentState (line 171) | inline void enterQuiescentState(const int tid) {
function retire (line 179) | inline void retire(const int tid, T* p) {
function debugPrintStatus (line 198) | void debugPrintStatus(const int tid) {
function initThread (line 203) | void initThread(const int tid) {
function deinitThread (line 212) | void deinitThread(const int tid) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/record_manager.h
function CallbackReturn (line 21) | inline CallbackReturn callbackReturnTrue(CallbackArg arg) {
function check_duplicates (line 27) | check_duplicates(void) {}
function check_duplicates (line 29) | check_duplicates(void) {
function clearCounters (line 47) | void clearCounters(void) {}
function registerThread (line 48) | void registerThread(const int tid) {}
function unregisterThread (line 49) | void unregisterThread(const int tid) {}
function printStatus (line 50) | void printStatus() {}
function qUnprotectAll (line 51) | inline void qUnprotectAll(const int tid) {}
function getReclaimers (line 52) | inline void getReclaimers(const int tid, void ** const reclaimers, int i...
function enterQuiescentState (line 53) | inline void enterQuiescentState(const int tid) {}
function leaveQuiescentStateForEach (line 54) | inline void leaveQuiescentStateForEach(const int tid) {}
function leaveQuiescentState (line 55) | inline void leaveQuiescentState(const int tid, const bool callForEach) {}
function initThread (line 152) | void initThread(const int tid) {
function deinitThread (line 159) | void deinitThread(const int tid) {
function clearCounters (line 164) | void clearCounters() {
function printStatus (line 167) | void printStatus(void) {
function isProtected (line 182) | bool isProtected(const int tid, T * const obj) {
function unprotect (line 192) | void unprotect(const int tid, T * const obj) {
function isQProtected (line 205) | bool isQProtected(const int tid, T * const obj) {
function qUnprotectAll (line 209) | inline void qUnprotectAll(const int tid) {
function isQuiescent (line 215) | inline bool isQuiescent(const int tid) {
function enterQuiescentState (line 218) | inline void enterQuiescentState(const int tid) {
function leaveQuiescentState (line 229) | inline void leaveQuiescentState(const int tid) {
function unretireLast (line 243) | void unretireLast(const int tid) {
function retire (line 250) | void retire(const int tid, T * const p) {
function T (line 256) | T * allocate(const int tid) {
function deallocate (line 263) | void deallocate(const int tid, T * const p) {
function shouldHelp (line 268) | inline static bool shouldHelp() { // FOR DEBUGGING PURPOSES
function supportsCrashRecovery (line 271) | inline static bool supportsCrashRecovery() {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/record_manager_single_type.h
type typename (line 50) | typedef typename Alloc::template
type typename (line 51) | typedef typename Pool::template
type typename (line 52) | typedef typename Reclaim::template
function initThread (line 77) | void initThread(const int tid) {
function deinitThread (line 83) | void deinitThread(const int tid) {
function clearCounters (line 87) | inline void clearCounters() {
function shouldHelp (line 91) | inline static bool shouldHelp() { // FOR DEBUGGING PURPOSES
function isProtected (line 94) | inline bool isProtected(const int tid, record_pointer obj) {
function unprotect (line 101) | inline void unprotect(const int tid, record_pointer obj) {
function qUnprotectAll (line 108) | inline void qUnprotectAll(const int tid) {
function isQProtected (line 112) | inline bool isQProtected(const int tid, record_pointer obj) {
function supportsCrashRecovery (line 116) | inline static bool supportsCrashRecovery() {
function quiescenceIsPerRecordType (line 119) | inline static bool quiescenceIsPerRecordType() {
function isQuiescent (line 122) | inline bool isQuiescent(const int tid) {
function enterQuiescentState (line 127) | inline void enterQuiescentState(const int tid) {
function leaveQuiescentState (line 131) | inline void leaveQuiescentState(const int tid, void * const * const recl...
function retire (line 137) | inline void retire(const int tid, record_pointer p) {
function unretireLast (line 143) | inline void unretireLast(const int tid) {
function record_pointer (line 149) | inline record_pointer allocate(const int tid) {
function deallocate (line 153) | inline void deallocate(const int tid, record_pointer p) {
function printStatus (line 158) | void printStatus(void) {
FILE: datastructures/trevor_brown_abtree/common/recordmgr/recovery_manager.h
type sigaction (line 12) | struct sigaction { void * sa_sigaction; int sa_flags; int sa_mask; }
type siginfo_t (line 13) | struct siginfo_t {}
type sigjmp_buf (line 14) | struct sigjmp_buf {}
type sigaction (line 41) | struct sigaction
type sigaction (line 44) | struct sigaction
function getTidInefficient (line 118) | inline int getTidInefficient(const pthread_t me) {
function getTidInefficientErrno (line 133) | inline int getTidInefficientErrno() {
function getTid_pthread_getspecific (line 149) | inline int getTid_pthread_getspecific() {
function pthread_t (line 158) | inline pthread_t getPthread(const int tid) {
function initThread (line 162) | void initThread(const int tid) {
function unblockCrashRecoverySignal (line 177) | void unblockCrashRecoverySignal() {
FILE: datastructures/trevor_brown_abtree/common/rq/rq_dcssp.h
function contains (line 36) | bool contains(T ** nullTerminatedArray, T * element) {
function contains (line 44) | bool contains(T * array, const int numElements, T element) {
type __rq_thread_data (line 57) | struct __rq_thread_data {
function initThread (line 139) | void initThread(const int tid) {
function deinitThread (line 158) | void deinitThread(const int tid) {
function init_node (line 173) | inline void init_node(const int tid, NodeType * const node) {
function write_addr (line 186) | void write_addr(const int tid, T volatile * const addr, const T val) {
function T (line 198) | T read_addr(const int tid, T volatile * const addr) {
function announce_physical_deletion (line 207) | void announce_physical_deletion(const int tid, NodeType * const * const ...
function physical_deletion_failed (line 221) | void physical_deletion_failed(const int tid, NodeType * const * const de...
function physical_deletion_succeeded (line 231) | void physical_deletion_succeeded(const int tid, NodeType * const * const...
function set_deletion_timestamps (line 256) | inline void set_deletion_timestamps(
function T (line 274) | T linearize_update_at_write(
function T (line 325) | T linearize_update_at_cas(
function traversal_start (line 384) | inline void traversal_start(const int tid) {
function traversal_try_add (line 576) | inline void traversal_try_add(const int tid, NodeType * const node, K * ...
function traversal_end (line 611) | void traversal_end(const int tid, K * const rqResultKeys, V * const rqRe...
FILE: datastructures/trevor_brown_abtree/common/rq/rq_debugging.h
function string (line 37) | string twoDigits(int x) {
function DEBUG_RECORD_RQ_VISITED (line 95) | inline void DEBUG_RECORD_RQ_VISITED(const int tid, const long long ts, c...
function DEBUG_RECORD_RQ_SIZE (line 102) | inline void DEBUG_RECORD_RQ_SIZE(const int size) {
function DEBUG_RECORD_UPDATE_CHECKSUM (line 109) | void DEBUG_RECORD_UPDATE_CHECKSUM(const int tid, const long long timesta...
function DEBUG_RECORD_RQ_CHECKSUM (line 138) | void DEBUG_RECORD_RQ_CHECKSUM(const int tid, const long long timestamp, ...
function DEBUG_INIT_RQPROVIDER (line 151) | void DEBUG_INIT_RQPROVIDER(const int numProcesses) {
function DEBUG_VALIDATE_RQ (line 179) | void DEBUG_VALIDATE_RQ(const int numProcesses) {
function DEBUG_DEINIT_RQPROVIDER (line 264) | void DEBUG_DEINIT_RQPROVIDER(const int numProcesses) {
FILE: datastructures/trevor_brown_abtree/common/rq/rq_htm_rwlock.h
type __rq_thread_data (line 34) | struct __rq_thread_data {
function initThread (line 94) | void initThread(const int tid) {
function deinitThread (line 112) | void deinitThread(const int tid) {
function init_node (line 121) | inline void init_node(const int tid, NodeType * const node) {
function write_addr (line 130) | void write_addr(const int tid, T volatile * const addr, const T val) {
function T (line 138) | T read_addr(const int tid, T volatile * const addr) {
function announce_physical_deletion (line 145) | void announce_physical_deletion(const int tid, NodeType * const * const ...
function physical_deletion_failed (line 159) | void physical_deletion_failed(const int tid, NodeType * const * const de...
function physical_deletion_succeeded (line 169) | void physical_deletion_succeeded(const int tid, NodeType * const * const...
function set_deletion_timestamps (line 194) | inline void set_deletion_timestamps(
function T (line 212) | T linearize_update_at_write(
function T (line 265) | T linearize_update_at_cas(
function traversal_start (line 326) | inline void traversal_start(const int tid) {
function traversal_try_add (line 436) | inline void traversal_try_add(const int tid, NodeType * const node, Node...
function traversal_end (line 471) | void traversal_end(const int tid, K * const rqResultKeys, V * const rqRe...
FILE: datastructures/trevor_brown_abtree/common/rq/rq_rwlock.h
type __rq_thread_data (line 26) | struct __rq_thread_data {
function initThread (line 72) | void initThread(const int tid) {
function deinitThread (line 85) | void deinitThread(const int tid) {
function init_node (line 94) | inline void init_node(const int tid, NodeType * const node) {
function write_addr (line 103) | void write_addr(const int tid, T volatile * const addr, const T val) {
function T (line 111) | T read_addr(const int tid, T volatile * const addr) {
function announce_physical_deletion (line 118) | void announce_physical_deletion(const int tid, NodeType * const * const ...
function physical_deletion_failed (line 132) | void physical_deletion_failed(const int tid, NodeType * const * const de...
function physical_deletion_succeeded (line 145) | void physical_deletion_succeeded(const int tid, NodeType * const * const...
function set_deletion_timestamps (line 170) | inline void set_deletion_timestamps(
function T (line 188) | T linearize_update_at_write(
function T (line 222) | T linearize_update_at_cas(
function traversal_start (line 262) | inline void traversal_start(const int tid) {
function traversal_try_add (line 356) | inline void traversal_try_add(const int tid, NodeType * const node, Node...
function traversal_end (line 391) | void traversal_end(const int tid, K * const rqResultKeys, V * const rqRe...
FILE: datastructures/trevor_brown_abtree/common/rq/rq_snapcollector.h
type __rq_thread_data (line 33) | struct __rq_thread_data {
function initThread (line 89) | void initThread(const int tid) {
function deinitThread (line 99) | void deinitThread(const int tid) {
function init_node (line 106) | inline void init_node(const int tid, NodeType * const node) {}
function write_addr (line 112) | void write_addr(const int tid, T volatile * const addr, const T val) {
function T (line 120) | T read_addr(const int tid, T volatile * const addr) {
function search_report_target_key (line 128) | inline void search_report_target_key(const int tid, const K key, NodeTyp...
function insert_readonly_report_target_key (line 142) | inline void insert_readonly_report_target_key(const int tid, NodeType * ...
function traversal_is_active (line 156) | inline bool traversal_is_active(const int tid) {
function physical_deletion_failed (line 184) | inline void physical_deletion_failed(const int tid, NodeType * const * c...
function physical_deletion_succeeded (line 189) | inline void physical_deletion_succeeded(const int tid, NodeType * const ...
function T (line 199) | T linearize_update_at_write(
function T (line 233) | T linearize_update_at_cas(
function traversal_start (line 268) | inline void traversal_start(const int tid) {
function NodeType (line 295) | inline NodeType * traversal_try_add(const int tid, NodeType * const node...
function traversal_end (line 304) | void traversal_end(const int tid, K * const rqResultKeys, V * const rqRe...
FILE: datastructures/trevor_brown_abtree/common/rq/rq_unsafe.h
type __rq_thread_data (line 22) | struct __rq_thread_data {
function initThread (line 59) | void initThread(const int tid) {
function deinitThread (line 66) | void deinitThread(const int tid) {
function init_node (line 73) | inline void init_node(const int tid, NodeType * const node) {}
function write_addr (line 79) | void write_addr(const int tid, T volatile * const addr, const T val) {
function T (line 87) | T read_addr(const int tid, T volatile * const addr) {
function announce_physical_deletion (line 94) | inline void announce_physical_deletion(const int tid, NodeType * const *...
function physical_deletion_failed (line 99) | inline void physical_deletion_failed(const int tid, NodeType * const * c...
function physical_deletion_succeeded (line 104) | inline void physical_deletion_succeeded(const int tid, NodeType * const ...
function T (line 114) | T linearize_update_at_write(
function T (line 152) | T linearize_update_at_cas(
function traversal_start (line 196) | inline void traversal_start(const int tid) {
function traversal_try_add (line 206) | inline void traversal_try_add(const int tid, NodeType * const node, K * ...
function traversal_end (line 229) | inline void traversal_end(const int tid, K * const rqResultKeys, V * con...
FILE: datastructures/trevor_brown_abtree/common/rq/snapcollector/reportitem.h
type ReportType (line 11) | enum ReportType {Add, Remove}
function getOrdinalForReportType (line 13) | static int getOrdinalForReportType(ReportType t) {
function class (line 17) | class ReportItem {
function class (line 35) | class CompactReportItem {
FILE: datastructures/trevor_brown_abtree/common/rq/snapcollector/snapcollector.h
function class (line 22) | class NodeWrapper {
function __retireAllReports (line 71) | void __retireAllReports(const int tid, std::vector<CompactReportItem *> ...
function __deallocateAllReports (line 80) | void __deallocateAllReports(const int tid, std::vector<CompactReportItem...
function IsActive (line 215) | bool IsActive() {
function Deactivate (line 251) | void Deactivate(pthread_rwlock_t * const rwlock, volatile long long * ti...
function BlockFurtherReports (line 265) | void BlockFurtherReports() {
function NodeType (line 326) | NodeType * GetNext(int tid) {
FILE: datastructures/trevor_brown_abtree/common/rq/snapcollector/snapcollector_test.cpp
class Node (line 16) | class Node {
method Node (line 24) | Node(int key) : key(key) {}
class DataStructure (line 27) | class DataStructure {
method isLogicallyDeleted (line 29) | inline bool isLogicallyDeleted(const int tid, Node * node) {
method getKeys (line 33) | inline int getKeys(const int tid, Node * node, int * const outputKeys) {
method isInRange (line 38) | bool isInRange(const int& key, const int& lo, const int& hi) {
function main (line 46) | int main(int argc, char** argv) {
FILE: datastructures/trevor_brown_abtree/common/rwlock.h
function class (line 22) | class RWLock {
function class (line 61) | class RWLock {
function class (line 106) | class RWLock {
FILE: datastructures/trevor_brown_abtree/ds/brown_ext_abtree_lf/brown_ext_abtree_lf.h
function namespace (line 55) | namespace abtree_ns {
FILE: datastructures/trevor_brown_abtree/ds/brown_ext_abtree_lf/brown_ext_abtree_lf_adapter.h
function initThread (line 37) | void initThread(const int tid) {
function deinitThread (line 40) | void deinitThread(const int tid) {
function contains (line 44) | bool contains(const int tid, const K& key) {
function rangeQuery (line 59) | int rangeQuery(const int tid, const K& lo, const K& hi, K * const result...
function getSize (line 65) | int getSize() {
function printSummary (line 68) | void printSummary() {
function getKeyChecksum (line 76) | long long getKeyChecksum() {
function validateStructure (line 79) | bool validateStructure() {
function printObjectSizes (line 82) | void printObjectSizes() {
FILE: datastructures/trevor_brown_abtree/minimal_example.cpp
function main (line 22) | int main(int argc, char** argv) {
FILE: datastructures/trevor_brown_natarajan/TrevorBrownNatarajanTree.hpp
class TrevorBrownNatarajanTree (line 16) | class TrevorBrownNatarajanTree {
method TrevorBrownNatarajanTree (line 22) | TrevorBrownNatarajanTree(int numThreads) {
method add (line 36) | bool add(K key, const int tid=0) {
method remove (line 46) | bool remove(K key, const int tid=0) {
method contains (line 55) | bool contains(K key, const int tid=0) {
method addAll (line 66) | void addAll(K** keys, int size, const int tid=0) {
method className (line 70) | static std::string className() { return "TrevorBrown-Natarajan-Tree"; }
FILE: datastructures/trevor_brown_natarajan/ds/natarajan_ext_bst_lf/natarajan_ext_bst_lf_adapter.h
function V (line 52) | V getNoValue() {
function initThread (line 56) | void initThread(const int tid) {
function deinitThread (line 59) | void deinitThread(const int tid) {
function contains (line 63) | bool contains(const int tid, const K& key) {
function V (line 66) | V insert(const int tid, const K& key, const V& val) {
function V (line 69) | V insertIfAbsent(const int tid, const K& key, const V& val) {
function V (line 72) | V erase(const int tid, const K& key) {
function V (line 75) | V find(const int tid, const K& key) {
function rangeQuery (line 78) | int rangeQuery(const int tid, const K& lo, const K& hi, K * const result...
function getSize (line 84) | int getSize() {
function printSummary (line 87) | void printSummary() {
function getKeyChecksum (line 90) | long long getKeyChecksum() {
function validateStructure (line 93) | bool validateStructure() {
function printObjectSizes (line 96) | void printObjectSizes() {
FILE: datastructures/trevor_brown_natarajan/ds/natarajan_ext_bst_lf/natarajan_ext_bst_lf_stage1.h
type Word (line 88) | typedef uintptr_t Word;
type node_t (line 109) | struct node_t
type node_t (line 110) | struct node_t
type node_t (line 113) | struct node_t
type node_t (line 121) | struct node_t
type node_t (line 170) | struct node_t
type node_t (line 171) | struct node_t
function freeSubtree (line 185) | void freeSubtree(node_t<skey_t, sval_t> * curr) {
function initThread (line 200) | void initThread(const int tid) {
function deinitThread (line 206) | void deinitThread(const int tid) {
function sval_t (line 212) | sval_t insertIfAbsent(const int tid, skey_t key, sval_t item) {
function sval_t (line 224) | sval_t erase(const int tid, skey_t key) {
function sval_t (line 236) | sval_t find(const int tid, skey_t key) {
function getKeyChecksum (line 259) | long long getKeyChecksum(node_t<skey_t, sval_t> * curr) {
function getKeyChecksum (line 267) | long long getKeyChecksum() {
function getSize (line 271) | long long getSize(node_t<skey_t, sval_t> * curr) {
function validateStructure (line 279) | bool validateStructure() {
function getSize (line 283) | long long getSize() {
function getSizeInNodes (line 287) | long long getSizeInNodes(node_t<skey_t, sval_t> * const curr) {
function getSizeInNodes (line 293) | long long getSizeInNodes() {
function printSummary (line 297) | void printSummary() {
FILE: datastructures/trevor_brown_natarajan/ds/natarajan_ext_bst_lf/natarajan_ext_bst_lf_stage2_impl.h
function SetBit (line 54) | static inline bool SetBit(volatile size_t *array, int bit) {
function mark_Node (line 60) | static bool mark_Node(volatile AO_t * word) {
FILE: graphs/BenchmarkLatencyCounter.hpp
class BenchmarkLatencyCounter (line 28) | class BenchmarkLatencyCounter {
type Result (line 41) | struct Result {
method BenchmarkLatencyCounter (line 50) | BenchmarkLatencyCounter(int numThreads) {
method Result (line 59) | Result latencyBenchmark(std::string& className) {
method allLatencyTests (line 158) | static void allLatencyTests() {
FILE: graphs/BenchmarkLatencyQueues.hpp
class BenchmarkLatencyQueues (line 28) | class BenchmarkLatencyQueues {
type UserData (line 31) | struct UserData {
method UserData (line 34) | UserData(long long lseq, int ltid) {
method UserData (line 38) | UserData() {
method UserData (line 42) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
type Result (line 49) | struct Result {
method Result (line 56) | Result() { }
method Result (line 58) | Result(const Result &other) {
method BenchmarkLatencyQueues (line 84) | BenchmarkLatencyQueues(int numThreads, int numRuns, seconds testLength) {
method latencyBurstBenchmark (line 100) | void latencyBurstBenchmark() {
method allLatencyTests (line 237) | static void allLatencyTests() {
FILE: graphs/BenchmarkMaps.hpp
type UserData (line 25) | struct UserData {
method UserData (line 28) | UserData(long long lseq, int ltid=0) {
method UserData (line 32) | UserData() {
method UserData (line 36) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
type std (line 50) | namespace std {
type hash<UserData> (line 52) | struct hash<UserData> {
class BenchmarkMaps (line 65) | class BenchmarkMaps {
type Result (line 68) | struct Result {
method Result (line 75) | Result() { }
method Result (line 77) | Result(const Result &other) {
method BenchmarkMaps (line 95) | BenchmarkMaps(int numThreads) {
method benchmark (line 106) | long long benchmark(const int updateRatio, const seconds testLengthSec...
method randomLong (line 242) | uint64_t randomLong(uint64_t x) {
FILE: graphs/BenchmarkQueues.hpp
type UserData (line 25) | struct UserData {
method UserData (line 28) | UserData(long long lseq, int ltid) {
method UserData (line 32) | UserData() {
method UserData (line 36) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
class BenchmarkQueues (line 60) | class BenchmarkQueues {
type Result (line 64) | struct Result {
method Result (line 71) | Result() { }
method Result (line 73) | Result(const Result &other) {
method BenchmarkQueues (line 99) | BenchmarkQueues(int numThreads) {
method enqDeq (line 109) | uint64_t enqDeq(std::string& className, const long numPairs, const int...
method burst (line 168) | void burst(std::string& className, uint64_t& resultsEnq, uint64_t& res...
FILE: graphs/BenchmarkSPS.hpp
class BenchmarkSPS (line 33) | class BenchmarkSPS {
type UserData (line 39) | struct UserData {
method UserData (line 42) | UserData(long long lseq, int ltid) {
method UserData (line 46) | UserData() {
method UserData (line 50) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
method BenchmarkSPS (line 57) | BenchmarkSPS(int numThreads) {
method benchmarkSPSInteger (line 66) | uint64_t benchmarkSPSInteger(std::string& className, const seconds tes...
method benchmarkSPSObject (line 168) | uint64_t benchmarkSPSObject(std::string& className, const seconds test...
method randomLong (line 269) | uint64_t randomLong(uint64_t x) {
FILE: graphs/BenchmarkSets.hpp
type UserData (line 25) | struct UserData {
method UserData (line 28) | UserData(long long lseq, int ltid=0) {
method UserData (line 32) | UserData() {
method UserData (line 36) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
type std (line 50) | namespace std {
type hash<UserData> (line 52) | struct hash<UserData> {
class BenchmarkSets (line 65) | class BenchmarkSets {
type Result (line 68) | struct Result {
method Result (line 75) | Result() { }
method Result (line 77) | Result(const Result &other) {
method BenchmarkSets (line 95) | BenchmarkSets(int numThreads) {
method benchmark (line 106) | long long benchmark(std::string& className, const int updateRatio, con...
method benchmarkRandomFill (line 215) | long long benchmarkRandomFill(std::string& className, const int update...
method randomLong (line 329) | uint64_t randomLong(uint64_t x) {
FILE: graphs/PBenchmarkQueues.hpp
type UserData (line 25) | struct UserData {
method UserData (line 28) | UserData(long long lseq, int ltid) {
method UserData (line 32) | UserData() {
method UserData (line 36) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
class PBenchmarkQueues (line 47) | class PBenchmarkQueues {
type Result (line 51) | struct Result {
method Result (line 58) | Result() { }
method Result (line 60) | Result(const Result &other) {
method PBenchmarkQueues (line 86) | PBenchmarkQueues(int numThreads) {
method enqDeq (line 97) | uint64_t enqDeq(std::string& className, const long numPairs, const int...
method enqDeqNoTransaction (line 165) | uint64_t enqDeqNoTransaction(std::string& className, const long numPai...
method burst (line 226) | void burst(std::string& className, uint64_t& resultsEnq, uint64_t& res...
FILE: graphs/PBenchmarkSPS.hpp
class PBenchmarkSPS (line 32) | class PBenchmarkSPS {
type UserData (line 38) | struct UserData {
method UserData (line 41) | UserData(long long lseq, int ltid) {
method UserData (line 45) | UserData() {
method UserData (line 49) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
method PBenchmarkSPS (line 56) | PBenchmarkSPS(int numThreads) {
method benchmarkSPSInteger (line 65) | uint64_t benchmarkSPSInteger(std::string& className, const seconds tes...
method randomLong (line 175) | static uint64_t randomLong(uint64_t x) {
FILE: graphs/PBenchmarkSets.hpp
type UserData (line 24) | struct UserData {
method UserData (line 27) | UserData(long long lseq, int ltid=0) {
method UserData (line 31) | UserData() {
method UserData (line 35) | UserData(const UserData &other) : seq(other.seq), tid(other.tid) { }
type std (line 46) | namespace std {
type hash<UserData> (line 48) | struct hash<UserData> {
class PBenchmarkSets (line 70) | class PBenchmarkSets {
type Result (line 73) | struct Result {
method Result (line 80) | Result() { }
method Result (line 82) | Result(const Result &other) {
method benchmark (line 106) | long long benchmark(std::string& className, int numThreads, const int ...
method randomLong (line 248) | uint64_t randomLong(uint64_t x) {
FILE: graphs/latency-counter.cpp
function main (line 17) | int main(void) {
FILE: graphs/pq-ll-enq-deq.cpp
function main (line 15) | int main(void) {
FILE: graphs/pread-while-writing.cpp
function main (line 26) | int main(void) {
FILE: graphs/pset-hash-1k.cpp
function main (line 14) | int main(void) {
FILE: graphs/pset-ll-10k.cpp
function main (line 13) | int main(void) {
FILE: graphs/pset-ll-1k.cpp
function main (line 14) | int main(void) {
FILE: graphs/pset-tree-1k.cpp
function main (line 15) | int main(void) {
FILE: graphs/pset-tree-1m.cpp
function main (line 26) | int main(void) {
FILE: graphs/psps-integer.cpp
function main (line 21) | int main(void) {
FILE: graphs/q-array-enq-deq.cpp
function main (line 32) | int main(void) {
FILE: graphs/q-ll-enq-deq.cpp
function main (line 34) | int main(void) {
FILE: graphs/set-hash-1k.cpp
function main (line 20) | int main(void) {
FILE: graphs/set-ll-10k.cpp
function main (line 22) | int main(void) {
FILE: graphs/set-ll-1k.cpp
function main (line 22) | int main(void) {
FILE: graphs/set-tree-10k.cpp
function main (line 19) | int main(void) {
FILE: graphs/set-tree-1k.cpp
function main (line 20) | int main(void) {
FILE: graphs/set-tree-1m.cpp
function main (line 17) | int main(void) {
FILE: graphs/sps-integer.cpp
function main (line 30) | int main(void) {
FILE: graphs/sps-object.cpp
function main (line 29) | int main(void) {
FILE: pdatastructures/TMHashMap.hpp
class TMHashMap (line 10) | class TMHashMap {
type Node (line 13) | struct Node {
method Node (line 17) | Node(const K& k, const V& v) : key{k}, val{v} { }
method Node (line 18) | Node() {}
method TMHashMap (line 30) | TMHashMap(uint64_t capacity=4) : capacity{capacity} {
method className (line 49) | static std::string className() { return TM::className() + "-HashMap"; }
method rebuild (line 52) | void rebuild() {
method innerPut (line 79) | bool innerPut(const K& key, const V& value, V& oldValue, const bool sa...
method innerRemove (line 117) | bool innerRemove(const K& key, V& oldValue, const bool saveOldValue) {
method innerGet (line 143) | bool innerGet(const K& key, V& oldValue, const bool saveOldValue) {
method add (line 162) | bool add(const K& key) {
method remove (line 170) | bool remove(const K& key) {
method contains (line 177) | bool contains(const K& key) {
method addAll (line 185) | bool addAll(K** keys, const int size) {
FILE: pdatastructures/TMHashMapByRef.hpp
class TMHashMapByRef (line 10) | class TMHashMapByRef {
type Node (line 13) | struct Node {
method Node (line 17) | Node(const K& k, const V& v) : key{k}, val{v} { }
method Node (line 18) | Node() {}
method TMHashMapByRef (line 30) | TMHashMapByRef(uint64_t capacity=4) : capacity{capacity} {
method className (line 49) | static std::string className() { return TM::className() + "-HashMap"; }
method rebuild (line 52) | void rebuild() {
method innerPut (line 79) | bool innerPut(const K& key, const V& value, V& oldValue, const bool sa...
method innerRemove (line 117) | bool innerRemove(const K& key, V& oldValue, const bool saveOldValue) {
method innerGet (line 143) | bool innerGet(const K& key, V& oldValue, const bool saveOldValue) {
method add (line 162) | bool add(const K& key) {
method remove (line 172) | bool remove(const K& key) {
method contains (line 181) | bool contains(const K& key) {
method addAll (line 191) | bool addAll(K** keys, const int size) {
FILE: pdatastructures/TMLinkedListQueue.hpp
class TMLinkedListQueue (line 12) | class TMLinkedListQueue {
type Node (line 15) | struct Node {
method Node (line 18) | Node(T* userItem) : item{userItem} { }
method TMLinkedListQueue (line 26) | TMLinkedListQueue() {
method className (line 40) | static std::string className() { return TM::className() + "-LinkedList...
method enqueue (line 43) | bool enqueue(T* item) {
method T (line 53) | T* dequeue() {
FILE: pdatastructures/TMLinkedListSet.hpp
class TMLinkedListSet (line 11) | class TMLinkedListSet {
type Node (line 14) | struct Node {
method Node (line 17) | Node(const K& key) : key{key} { }
method Node (line 18) | Node(){ }
method TMLinkedListSet (line 26) | TMLinkedListSet() {
method className (line 53) | static std::string className() { return TM::className() + "-LinkedList...
method add (line 58) | bool add(K key) {
method remove (line 75) | bool remove(K key) {
method contains (line 90) | bool contains(K key) {
method find (line 99) | void find(const K& lkey, Node*& prev, Node*& node) {
method addAll (line 107) | bool addAll(K** keys, const int size) {
FILE: pdatastructures/TMLinkedListSetByRef.hpp
class TMLinkedListSetByRef (line 11) | class TMLinkedListSetByRef {
type Node (line 14) | struct Node {
method Node (line 17) | Node(const K& key) : key{key} { }
method Node (line 18) | Node(){ }
method TMLinkedListSetByRef (line 26) | TMLinkedListSetByRef() {
method className (line 53) | static std::string className() { return TM::className() + "-LinkedList...
method add (line 58) | bool add(K key) {
method remove (line 75) | bool remove(K key) {
method contains (line 91) | bool contains(K key) {
method find (line 101) | void find(const K& lkey, Node*& prev, Node*& node) {
method addAll (line 109) | bool addAll(K** keys, const int size) {
FILE: pdatastructures/TMRedBlackTree.hpp
class TMRedBlackTree (line 11) | class TMRedBlackTree {
type Node (line 15) | struct Node {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method assignAndFreeIfNull (line 28) | inline void assignAndFreeIfNull(TMTYPE<Node*>& z, Node* w) {
method TMRedBlackTree (line 38) | TMRedBlackTree(int numThreads=0){ }
method deleteAll (line 48) | void deleteAll(Node* rt){
method isRed (line 65) | bool isRed(Node* x) {
method size (line 71) | int size(Node* x) {
method size (line 81) | int size() {
method isEmpty (line 89) | bool isEmpty() {
method innerGet (line 105) | bool innerGet(K key, V& oldValue, const bool saveOldValue) {
method get (line 113) | bool get(Node* x, K& key) {
method containsKey (line 129) | bool containsKey(const K& key) {
method innerPut (line 147) | bool innerPut(const K& key, const V& value) {
method Node (line 155) | Node* put(Node* h, const K& key, const V& val, bool& ret) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method deleteMin (line 180) | void deleteMin() {
method Node (line 191) | Node* deleteMin(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method deleteMax (line 205) | void deleteMax() {
method Node (line 218) | Node* deleteMax(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method innerRemove (line 239) | void innerRemove(K key) {
method Node (line 248) | Node* deleteKey(Node* h, const K& key) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 284) | Node* rotateRight(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 297) | Node* rotateLeft(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method flipColors (line 310) | void flipColors(Node* h) {
method Node (line 322) | Node* moveRedLeft(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 337) | Node* moveRedRight(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 349) | Node* balance(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method height (line 369) | int height() {
method height (line 372) | int height(Node* x) {
method K (line 386) | K* min() {
method Node (line 392) | Node* min(Node* x) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 403) | K* max() {
method Node (line 409) | Node* max(Node* x) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 423) | K* floor(const K& key) {
method Node (line 432) | Node* floor(Node* x, const K& key) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 448) | K* ceiling(const K& key) {
method Node (line 457) | Node* ceiling(Node* x, const K& key) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 473) | K* select(int k) {
method Node (line 482) | Node* select(Node* x, int k) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method rank (line 497) | int rank(const K& key) {
method rank (line 503) | int rank(const K& key, Node* x) {
method size (line 525) | int size(const K& lo, const K& hi) {
method check (line 538) | bool check() {
method isBST (line 549) | bool isBST() {
method isBST (line 556) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 565) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 566) | bool isSizeConsistent(Node* x) {
method is23 (line 585) | bool is23() { return is23(root); }
method is23 (line 586) | bool is23(Node* x) {
method isBalanced (line 595) | bool isBalanced() {
method isBalanced (line 606) | bool isBalanced(Node* x, int black) {
method add (line 615) | bool add(K key, const int tid=0) {
method remove (line 622) | bool remove(K key, const int tid=0) {
method contains (line 631) | bool contains(K key, const int tid=0) {
method addAll (line 638) | void addAll(K** keys, int size, const int tid=0) {
method className (line 642) | static std::string className() { return TM::className() + "-RedBlackTr...
FILE: pdatastructures/TMRedBlackTreeByRef.hpp
class TMRedBlackTreeByRef (line 11) | class TMRedBlackTreeByRef {
type Node (line 15) | struct Node {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method assignAndFreeIfNull (line 28) | inline void assignAndFreeIfNull(TMTYPE<Node*>& z, Node* w) {
method TMRedBlackTreeByRef (line 38) | TMRedBlackTreeByRef(int numThreads=0){ }
method isRed (line 54) | bool isRed(Node* x) {
method size (line 60) | int size(Node* x) {
method size (line 70) | int size() {
method isEmpty (line 78) | bool isEmpty() {
method innerGet (line 94) | bool innerGet(K key, V& oldValue, const bool saveOldValue) {
method get (line 102) | bool get(Node* x, K& key) {
method containsKey (line 118) | bool containsKey(const K& key) {
method innerPut (line 136) | bool innerPut(const K& key, const V& value) {
method Node (line 144) | Node* put(Node* h, const K& key, const V& val, bool& ret) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method deleteMin (line 177) | void deleteMin() {
method Node (line 188) | Node* deleteMin(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method deleteMax (line 202) | void deleteMax() {
method Node (line 215) | Node* deleteMax(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method innerRemove (line 236) | void innerRemove(K key) {
method Node (line 245) | Node* deleteKey(Node* h, const K& key) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 281) | Node* rotateRight(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 294) | Node* rotateLeft(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method flipColors (line 307) | void flipColors(Node* h) {
method Node (line 319) | Node* moveRedLeft(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 334) | Node* moveRedRight(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method Node (line 346) | Node* balance(Node* h) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method height (line 366) | int height() {
method height (line 369) | int height(Node* x) {
method K (line 383) | K* min() {
method Node (line 389) | Node* min(Node* x) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 400) | K* max() {
method Node (line 406) | Node* max(Node* x) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 420) | K* floor(const K& key) {
method Node (line 429) | Node* floor(Node* x, const K& key) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 445) | K* ceiling(const K& key) {
method Node (line 454) | Node* ceiling(Node* x, const K& key) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method K (line 470) | K* select(int k) {
method Node (line 479) | Node* select(Node* x, int k) {
method Node (line 22) | Node(const K& key, const V& val, int64_t color, int64_t size) : key{...
method Node (line 23) | Node() {}
method rank (line 494) | int rank(const K& key) {
method rank (line 500) | int rank(const K& key, Node* x) {
method size (line 522) | int size(const K& lo, const K& hi) {
method check (line 535) | bool check() {
method isBST (line 546) | bool isBST() {
method isBST (line 553) | bool isBST(Node* x, K* min, K* max) {
method isSizeConsistent (line 562) | bool isSizeConsistent() { return isSizeConsistent(root); }
method isSizeConsistent (line 563) | bool isSizeConsistent(Node* x) {
method is23 (line 582) | bool is23() { return is23(root); }
method is23 (line 583) | bool is23(Node* x) {
method isBalanced (line 592) | bool isBalanced() {
method isBalanced (line 603) | bool isBalanced(Node* x, int black) {
method add (line 612) | bool add(K key, const int tid=0) {
method remove (line 621) | bool remove(K key, const int tid=0) {
method contains (line 631) | bool contains(K key, const int tid=0) {
method addAll (line 640) | void addAll(K** keys, int size, const int tid=0) {
method className (line 644) | static std::string className() { return TM::className() + "-RedBlackTr...
FILE: pdatastructures/pqueues/HazardPointers.hpp
class HazardPointers (line 40) | class HazardPointers {
method HazardPointers (line 59) | HazardPointers(int maxHPs, int maxThreads) : maxHPs{maxHPs}, maxThread...
method HazardPointers (line 68) | HazardPointers(int maxHPs, int maxThreads, std::function<void(T*,int)>...
method clear (line 91) | void clear(const int tid) {
method clearOne (line 101) | void clearOne(int ihp, const int tid) {
method T (line 109) | T* protect(int index, const std::atomic<T*>& atom, const int tid) {
method T (line 119) | T* get(int index, const int tid){
method T (line 126) | T* protectPtr(int index, T* ptr, const int tid) {
method T (line 137) | T* protectPtrRelease(int index, T* ptr, const int tid) {
method retire (line 146) | void retire(T* ptr, const int tid) {
FILE: pdatastructures/pqueues/MichaelScottQueue.hpp
class MichaelScottQueue (line 61) | class MichaelScottQueue {
type Node (line 64) | struct Node {
method Node (line 68) | Node(T userItem) : item{userItem}, next{nullptr} { }
method casNext (line 70) | bool casNext(Node *cmp, Node *val) {
method casTail (line 75) | bool casTail(Node *cmp, Node *val) {
method casHead (line 79) | bool casHead(Node *cmp, Node *val) {
method MichaelScottQueue (line 99) | MichaelScottQueue(int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
method className (line 111) | static std::string className() { return "MichaelScottQueue"; }
method enqueue (line 113) | void enqueue(T item, const int tid) {
method T (line 136) | T dequeue(const int tid) {
FILE: pdatastructures/pqueues/PFriedmanQueue.hpp
class PFriedmanQueue (line 79) | class PFriedmanQueue {
type Node (line 84) | struct Node {
method Node (line 88) | Node(T item) : value{item} { }
method casNext (line 89) | bool casNext(Node *cmp, Node *val) {
method casDeqTID (line 92) | bool casDeqTID(int cmp, int val) {
method casTail (line 97) | bool casTail(Node *cmp, Node *val) {
method casHead (line 101) | bool casHead(Node *cmp, Node *val) {
method internalDelete (line 122) | static void internalDelete(TN* obj) {
method TN (line 137) | static TN* internalNew(Args&&... args) {
method recover (line 166) | void recover() {
method PFriedmanQueue (line 214) | PFriedmanQueue(int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
method className (line 243) | static std::string className() { return "PFriedmanQueue"; }
method enqueue (line 250) | void enqueue(T item, const int tid) {
method T (line 281) | T dequeue(const int tid) {
FILE: pdatastructures/pqueues/PMDKLinkedListQueue.hpp
class PMDKLinkedListQueue (line 21) | class PMDKLinkedListQueue {
type Node (line 24) | struct Node {
method Node (line 27) | Node(T userItem) : item{userItem} { }
method PMDKLinkedListQueue (line 37) | PMDKLinkedListQueue(unsigned int maxThreads=0) {
method className (line 55) | static std::string className() { return "PMDK-LinkedListQueue"; }
method enqueue (line 62) | bool enqueue(T item, const int tid=0) {
method T (line 76) | T dequeue(const int tid=0) {
FILE: pdatastructures/pqueues/PMichaelScottQueue.hpp
class PMichaelScottQueue (line 160) | class PMichaelScottQueue {
type Node (line 165) | struct Node {
method Node (line 168) | Node(T userItem) : item{userItem} { }
method casNext (line 169) | bool casNext(Node *cmp, Node *val) {
method casTail (line 174) | bool casTail(Node *cmp, Node *val) {
method casHead (line 178) | bool casHead(Node *cmp, Node *val) {
method internalDelete (line 194) | static void internalDelete(TN* obj) {
method TN (line 209) | static TN* internalNew(Args&&... args) {
method recover (line 237) | void recover() {
method PMichaelScottQueue (line 277) | PMichaelScottQueue(int maxThreads=MAX_THREADS) : maxThreads{maxThreads} {
method className (line 291) | static std::string className() { return "PMichaelScottQueue"; }
method enqueue (line 296) | void enqueue(T item, const int tid) {
method T (line 323) | T dequeue(const int tid) {
FILE: pdatastructures/pqueues/POFLFLinkedListQueue.hpp
class POFLFLinkedListQueue (line 30) | class POFLFLinkedListQueue : public poflf::tmbase {
type Node (line 33) | struct Node : poflf::tmbase {
method Node (line 36) | Node(T userItem) : item{userItem} { }
method POFLFLinkedListQueue (line 46) | POFLFLinkedListQueue(unsigned int maxThreads=0) {
method className (line 64) | static std::string className() { return "POF-LF-LinkedListQueue"; }
method enqueue (line 71) | bool enqueue(T item, const int tid=0) {
method T (line 85) | T dequeue(const int tid=0) {
FILE: pdatastructures/pqueues/POFLFMPLinkedListQueue.hpp
class POFLFMPLinkedListQueue (line 30) | class POFLFMPLinkedListQueue : public onefileptmlfmp::tmbase {
type Node (line 33) | struct Node : onefileptmlfmp::tmbase {
method Node (line 36) | Node(T userItem) : item{userItem} { }
method POFLFMPLinkedListQueue (line 46) | POFLFMPLinkedListQueue(unsigned int maxThreads=0) {
method className (line 64) | static std::string className() { return "POF-LF-MP-LinkedListQueue"; }
method enqueue (line 71) | bool enqueue(T item, const int tid=0) {
method T (line 85) | T dequeue(const int tid=0) {
FILE: pdatastructures/pqueues/POFWFLinkedListQueue.hpp
class POFWFLinkedListQueue (line 29) | class POFWFLinkedListQueue : public pofwf::tmbase {
type Node (line 32) | struct Node : pofwf::tmbase {
method Node (line 35) | Node(T userItem) : item{userItem} { }
method POFWFLinkedListQueue (line 45) | POFWFLinkedListQueue(unsigned int maxThreads=0) {
method className (line 63) | static std::string className() { return "POF-WF-LinkedListQueue"; }
method enqueue (line 70) | bool enqueue(T item, const int tid=0) {
method T (line 84) | T dequeue(const int tid=0) {
FILE: pdatastructures/pqueues/RomLRLinkedListQueue.hpp
class RomLRLinkedListQueue (line 21) | class RomLRLinkedListQueue {
type Node (line 24) | struct Node {
method Node (line 27) | Node(T userItem) : item{userItem} { }
method RomLRLinkedListQueue (line 37) | RomLRLinkedListQueue(unsigned int maxThreads=0) {
method className (line 55) | static std::string className() { return "RomulusLR-LinkedListQueue"; }
method enqueue (line 62) | bool enqueue(T item, const int tid=0) {
method T (line 76) | T dequeue(const int tid=0) {
FILE: pdatastructures/pqueues/RomLogLinkedListQueue.hpp
class RomLogLinkedListQueue (line 21) | class RomLogLinkedListQueue {
type Node (line 24) | struct Node {
method Node (line 27) | Node(T userItem) : item{userItem} { }
method RomLogLinkedListQueue (line 37) | RomLogLinkedListQueue(unsigned int maxThreads=0) {
method className (line 55) | static std::string className() { return "RomulusLog-LinkedListQueue"; }
method enqueue (line 62) | bool enqueue(T item, const int tid=0) {
method T (line 76) | T dequeue(const int tid=0) {
FILE: ptms/OneFilePTMLF.hpp
type poflf (line 63) | namespace poflf {
function seqidx2trans (line 107) | static inline uint64_t seqidx2trans(uint64_t seq, uint64_t idx) {
function trans2seq (line 110) | static inline uint64_t trans2seq(uint64_t trans) {
function trans2idx (line 113) | static inline uint64_t trans2idx(uint64_t trans) {
function flushFromTo (line 118) | static inline void flushFromTo(void* from, void* to) noexcept {
type ThreadCheckInCheckOut (line 131) | struct ThreadCheckInCheckOut {
class ThreadRegistry (line 143) | class ThreadRegistry
method ThreadRegistry (line 161) | ThreadRegistry() {
method register_thread_new (line 168) | int register_thread_new(void) {
method deregister_thread (line 187) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 192) | static inline uint64_t getMaxThreads(void) {
method getTID (line 197) | static inline int getTID(void) {
class ThreadRegistry (line 155) | class ThreadRegistry {
method ThreadRegistry (line 161) | ThreadRegistry() {
method register_thread_new (line 168) | int register_thread_new(void) {
method deregister_thread (line 187) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 192) | static inline uint64_t getMaxThreads(void) {
method getTID (line 197) | static inline int getTID(void) {
type tmtype (line 206) | struct tmtype
method tmtype (line 816) | tmtype() { }
method tmtype (line 818) | tmtype(T initVal) { pstore(initVal); }
method T (line 843) | T operator->() { return pload(); }
method T (line 861) | T* operator&() {
method isolated_store (line 868) | inline void isolated_store(T newVal) {
method pstore (line 875) | inline void pstore(T newVal) {
method T (line 893) | inline T pload() const {
type tmtypebase (line 209) | struct tmtypebase {
class EsLoco (line 238) | class EsLoco {
type block (line 240) | struct block {
method highestBit (line 261) | uint64_t highestBit(uint64_t val) {
method init (line 273) | void init(void* addressOfMemoryPool, size_t sizeOfMemoryPool, bool c...
method reset (line 292) | void reset() {
method getUsedSize (line 298) | uint64_t getUsedSize() {
method free (line 336) | void free(void* ptr) {
type tmbase (line 349) | struct tmbase {
type PWriteSetEntry (line 354) | struct PWriteSetEntry {
type PWriteSet (line 361) | struct PWriteSet {
method applyFromRecover (line 367) | void applyFromRecover() {
type PMetadata (line 379) | struct PMetadata {
type WriteSetEntry (line 391) | struct WriteSetEntry {
type WriteSet (line 402) | struct WriteSet {
method WriteSet (line 408) | WriteSet() {
method persistAndFlushLog (line 414) | inline void persistAndFlushLog(PWriteSet* const pwset) {
method flushModifications (line 426) | inline void flushModifications() {
method hash (line 431) | inline uint64_t hash(const void* addr) const {
method addOrReplace (line 436) | inline void addOrReplace(void* addr, uint64_t val) {
method lookupAddr (line 475) | inline uint64_t lookupAddr(const void* addr, uint64_t lval) {
method WriteSet (line 496) | WriteSet& operator = (const WriteSet &other) {
method apply (line 504) | inline void apply(uint64_t seq, const int tid) {
type OpData (line 518) | struct OpData
type OpData (line 524) | struct OpData {
type AbortedTx (line 533) | struct AbortedTx {}
class OneFileLF (line 536) | class OneFileLF
method OneFileLF (line 567) | OneFileLF() {
method className (line 578) | static std::string className() { return "OneFilePTM-LF"; }
method mapPersistentRegion (line 580) | void mapPersistentRegion(const char* filename, uint8_t* regionAddr, ...
method beginTx (line 638) | void beginTx(OpData& myopd, const int tid) {
method commitTx (line 653) | inline bool commitTx(OpData& myopd, const int tid) {
method R (line 677) | R transaction(F&& func) {
method transaction (line 699) | void transaction(F&& func) {
method R (line 722) | static R updateTx(F&& func) { return gOFLF.transaction<R>(func); }
method R (line 723) | static R readTx(F&& func) { return gOFLF.transaction<R>(func); }
method updateTx (line 724) | static void updateTx(F&& func) { gOFLF.transaction(func); }
method readTx (line 725) | static void readTx(F&& func) { gOFLF.transaction(func); }
method T (line 727) | static T* tmNew(Args&&... args) {
method tmDelete (line 735) | static void tmDelete(T* obj) {
method tmFree (line 750) | static void tmFree(void* obj) {
method pfree (line 763) | static void pfree(void* obj) {
method T (line 768) | static inline T* get_object(int idx) {
method put_object (line 773) | static inline void put_object(int idx, T* obj) {
method helpApply (line 780) | inline void helpApply(uint64_t lcurTx, const int tid) {
method recover (line 805) | void recover() {
class OneFileLF (line 555) | class OneFileLF {
method OneFileLF (line 567) | OneFileLF() {
method className (line 578) | static std::string className() { return "OneFilePTM-LF"; }
method mapPersistentRegion (line 580) | void mapPersistentRegion(const char* filename, uint8_t* regionAddr, ...
method beginTx (line 638) | void beginTx(OpData& myopd, const int tid) {
method commitTx (line 653) | inline bool commitTx(OpData& myopd, const int tid) {
method R (line 677) | R transaction(F&& func) {
method transaction (line 699) | void transaction(F&& func) {
method R (line 722) | static R updateTx(F&& func) { return gOFLF.transaction<R>(func); }
method R (line 723) | static R readTx(F&& func) { return gOFLF.transaction<R>(func); }
method updateTx (line 724) | static void updateTx(F&& func) { gOFLF.transaction(func); }
method readTx (line 725) | static void readTx(F&& func) { gOFLF.transaction(func); }
method T (line 727) | static T* tmNew(Args&&... args) {
method tmDelete (line 735) | static void tmDelete(T* obj) {
method tmFree (line 750) | static void tmFree(void* obj) {
method pfree (line 763) | static void pfree(void* obj) {
method T (line 768) | static inline T* get_object(int idx) {
method put_object (line 773) | static inline void put_object(int idx, T* obj) {
method helpApply (line 780) | inline void helpApply(uint64_t lcurTx, const int tid) {
method recover (line 805) | void recover() {
type tmtype (line 815) | struct tmtype : tmtypebase<T> {
method tmtype (line 816) | tmtype() { }
method tmtype (line 818) | tmtype(T initVal) { pstore(initVal); }
method T (line 843) | T operator->() { return pload(); }
method T (line 861) | T* operator&() {
method isolated_store (line 868) | inline void isolated_store(T newVal) {
method pstore (line 875) | inline void pstore(T newVal) {
method T (line 893) | inline T pload() const {
function R (line 909) | static R updateTx(F&& func) { return gOFLF.transaction<R>(func); }
function R (line 910) | static R readTx(F&& func) { return gOFLF.transaction<R>(func); }
function updateTx (line 911) | static void updateTx(F&& func) { gOFLF.transaction(func); }
function readTx (line 912) | static void readTx(F&& func) { gOFLF.transaction(func); }
function T (line 913) | T* tmNew(Args&&... args) { return OneFileLF::tmNew<T>(std::forward<Arg...
function tmDelete (line 914) | void tmDelete(T* obj) { OneFileLF::tmDelete<T>(obj); }
function T (line 915) | static T* get_object(int idx) { return OneFileLF::get_object<T>(idx); }
function put_object (line 916) | static void put_object(int idx, T* obj) { OneFileLF::put_object<T>(idx...
function tmFree (line 918) | inline static void tmFree(void* obj) { OneFileLF::tmFree(obj); }
function thread_registry_deregister_thread (line 934) | void thread_registry_deregister_thread(const int tid) {
FILE: ptms/OneFilePTMLFMultiProcess.hpp
type onefileptmlfmp (line 64) | namespace onefileptmlfmp {
function seqidx2trans (line 108) | static inline uint64_t seqidx2trans(uint64_t seq, uint64_t idx) {
function trans2seq (line 111) | static inline uint64_t trans2seq(uint64_t trans) {
function trans2idx (line 114) | static inline uint64_t trans2idx(uint64_t trans) {
function flushFromTo (line 119) | static inline void flushFromTo(void* from, void* to) noexcept {
type ThreadCheckInCheckOut (line 132) | struct ThreadCheckInCheckOut {
class ThreadRegistry (line 144) | class ThreadRegistry
method initRobustMutex (line 162) | void initRobustMutex(pthread_mutex_t* rmutex) {
method init (line 172) | void init(pthread_mutex_t* usedTID, std::atomic<int64_t>* maxTid, bo...
method register_thread_new (line 183) | int register_thread_new(void) {
method deregister_thread (line 201) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 206) | static inline uint64_t getMaxThreads(void) {
method getTID (line 211) | static inline int getTID(void) {
class ThreadRegistry (line 156) | class ThreadRegistry {
method initRobustMutex (line 162) | void initRobustMutex(pthread_mutex_t* rmutex) {
method init (line 172) | void init(pthread_mutex_t* usedTID, std::atomic<int64_t>* maxTid, bo...
method register_thread_new (line 183) | int register_thread_new(void) {
method deregister_thread (line 201) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 206) | static inline uint64_t getMaxThreads(void) {
method getTID (line 211) | static inline int getTID(void) {
type tmtype (line 220) | struct tmtype
method tmtype (line 835) | tmtype() { }
method tmtype (line 837) | tmtype(T initVal) { pstore(initVal); }
method T (line 862) | T operator->() { return pload(); }
method T (line 880) | T* operator&() {
method isolated_store (line 887) | inline void isolated_store(T newVal) {
method pstore (line 894) | inline void pstore(T newVal) {
method T (line 912) | inline T pload() const {
type tmtypebase (line 223) | struct tmtypebase {
class EsLoco (line 252) | class EsLoco {
type block (line 254) | struct block {
method highestBit (line 275) | uint64_t highestBit(uint64_t val) {
method init (line 287) | void init(void* addressOfMemoryPool, size_t sizeOfMemoryPool, bool c...
method reset (line 306) | void reset() {
method getUsedSize (line 312) | uint64_t getUsedSize() {
method free (line 350) | void free(void* ptr) {
type tmbase (line 363) | struct tmbase {
type PWriteSetEntry (line 368) | struct PWriteSetEntry {
type PWriteSet (line 375) | struct PWriteSet {
method applyFromRecover (line 381) | void applyFromRecover() {
type WriteSetEntry (line 392) | struct WriteSetEntry {
type WriteSet (line 403) | struct WriteSet {
method WriteSet (line 409) | WriteSet() {
method persistAndFlushLog (line 415) | inline void persistAndFlushLog(PWriteSet* const pwset) {
method flushModifications (line 427) | inline void flushModifications() {
method hash (line 432) | inline uint64_t hash(const void* addr) const {
method addOrReplace (line 437) | inline void addOrReplace(void* addr, uint64_t val) {
method lookupAddr (line 476) | inline uint64_t lookupAddr(const void* addr, uint64_t lval) {
method WriteSet (line 497) | WriteSet& operator = (const WriteSet &other) {
method apply (line 505) | inline void apply(uint64_t seq, const int tid) {
type PMetadata (line 520) | struct PMetadata {
type OpData (line 536) | struct OpData
type OpData (line 542) | struct OpData {
type AbortedTx (line 551) | struct AbortedTx {}
class OneFileLF (line 554) | class OneFileLF
method OneFileLF (line 585) | OneFileLF() {
method className (line 594) | static std::string className() { return "OneFilePTM-MultiProcess-LF"; }
method mapPersistentRegion (line 596) | void mapPersistentRegion(const char* filename, uint8_t* regionAddr, ...
method beginTx (line 657) | void beginTx(OpData& myopd, const int tid) {
method commitTx (line 672) | inline bool commitTx(OpData& myopd, const int tid) {
method R (line 696) | R transaction(F&& func) {
method transaction (line 718) | void transaction(F&& func) {
method R (line 741) | static R updateTx(F&& func) { return gOFLF.transaction<R>(func); }
method R (line 742) | static R readTx(F&& func) { return gOFLF.transaction<R>(func); }
method updateTx (line 743) | static void updateTx(F&& func) { gOFLF.transaction(func); }
method readTx (line 744) | static void readTx(F&& func) { gOFLF.transaction(func); }
method T (line 746) | static T* tmNew(Args&&... args) {
method tmDelete (line 754) | static void tmDelete(T* obj) {
method tmFree (line 769) | static void tmFree(void* obj) {
method pfree (line 782) | static void pfree(void* obj) {
method T (line 787) | static inline T* get_object(int idx) {
method put_object (line 792) | static inline void put_object(int idx, T* obj) {
method helpApply (line 799) | inline void helpApply(uint64_t lcurTx, const int tid) {
method recover (line 824) | void recover() {
class OneFileLF (line 573) | class OneFileLF {
method OneFileLF (line 585) | OneFileLF() {
method className (line 594) | static std::string className() { return "OneFilePTM-MultiProcess-LF"; }
method mapPersistentRegion (line 596) | void mapPersistentRegion(const char* filename, uint8_t* regionAddr, ...
method beginTx (line 657) | void beginTx(OpData& myopd, const int tid) {
method commitTx (line 672) | inline bool commitTx(OpData& myopd, const int tid) {
method R (line 696) | R transaction(F&& func) {
method transaction (line 718) | void transaction(F&& func) {
method R (line 741) | static R updateTx(F&& func) { return gOFLF.transaction<R>(func); }
method R (line 742) | static R readTx(F&& func) { return gOFLF.transaction<R>(func); }
method updateTx (line 743) | static void updateTx(F&& func) { gOFLF.transaction(func); }
method readTx (line 744) | static void readTx(F&& func) { gOFLF.transaction(func); }
method T (line 746) | static T* tmNew(Args&&... args) {
method tmDelete (line 754) | static void tmDelete(T* obj) {
method tmFree (line 769) | static void tmFree(void* obj) {
method pfree (line 782) | static void pfree(void* obj) {
method T (line 787) | static inline T* get_object(int idx) {
method put_object (line 792) | static inline void put_object(int idx, T* obj) {
method helpApply (line 799) | inline void helpApply(uint64_t lcurTx, const int tid) {
method recover (line 824) | void recover() {
type tmtype (line 834) | struct tmtype : tmtypebase<T> {
method tmtype (line 835) | tmtype() { }
method tmtype (line 837) | tmtype(T initVal) { pstore(initVal); }
method T (line 862) | T operator->() { return pload(); }
method T (line 880) | T* operator&() {
method isolated_store (line 887) | inline void isolated_store(T newVal) {
method pstore (line 894) | inline void pstore(T newVal) {
method T (line 912) | inline T pload() const {
function R (line 928) | static R updateTx(F&& func) { return gOFLF.transaction<R>(func); }
function R (line 929) | static R readTx(F&& func) { return gOFLF.transaction<R>(func); }
function updateTx (line 930) | static void updateTx(F&& func) { gOFLF.transaction(func); }
function readTx (line 931) | static void readTx(F&& func) { gOFLF.transaction(func); }
function T (line 932) | T* tmNew(Args&&... args) { return OneFileLF::tmNew<T>(std::forward<Arg...
function tmDelete (line 933) | void tmDelete(T* obj) { OneFileLF::tmDelete<T>(obj); }
function T (line 934) | static T* get_object(int idx) { return OneFileLF::get_object<T>(idx); }
function put_object (line 935) | static void put_object(int idx, T* obj) { OneFileLF::put_object<T>(idx...
function tmFree (line 937) | inline static void tmFree(void* obj) { OneFileLF::tmFree(obj); }
function thread_registry_deregister_thread (line 953) | void thread_registry_deregister_thread(const int tid) {
FILE: ptms/OneFilePTMWF.hpp
type pofwf (line 64) | namespace pofwf {
function seqidx2trans (line 108) | static inline uint64_t seqidx2trans(uint64_t seq, uint64_t idx) {
function trans2seq (line 111) | static inline uint64_t trans2seq(uint64_t trans) {
function trans2idx (line 114) | static inline uint64_t trans2idx(uint64_t trans) {
function flushFromTo (line 119) | static inline void flushFromTo(void* from, void* to) noexcept {
type ThreadCheckInCheckOut (line 132) | struct ThreadCheckInCheckOut {
class ThreadRegistry (line 144) | class ThreadRegistry
method ThreadRegistry (line 162) | ThreadRegistry() {
method register_thread_new (line 169) | int register_thread_new(void) {
method deregister_thread (line 188) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 193) | static inline uint64_t getMaxThreads(void) {
method getTID (line 198) | static inline int getTID(void) {
class ThreadRegistry (line 156) | class ThreadRegistry {
method ThreadRegistry (line 162) | ThreadRegistry() {
method register_thread_new (line 169) | int register_thread_new(void) {
method deregister_thread (line 188) | inline void deregister_thread(const int tid) {
method getMaxThreads (line 193) | static inline uint64_t getMaxThreads(void) {
method getTID (line 198) | static inline int getTID(void) {
type tmbase (line 207) | struct tmbase {
type TransFunc (line 214) | struct TransFunc : public tmbase {
method TransFunc (line 216) | TransFunc(F&& f) : func{f} { }
class HazardErasOF (line 229) | class HazardErasOF {
method HazardErasOF (line 240) | HazardErasOF(unsigned int maxThreads=REGISTRY_MAX_THREADS) : maxThre...
method clear (line 260) | inline void clear(const int tid) {
method set (line 265) | inline void set(uint64_t trans, const int tid) {
method addToRetiredListTx (line 270) | inline void addToRetiredListTx(TransFunc* tx, const int tid) {
method clean (line 283) | void clean(uint64_t curEra, const int tid) {
method canDelete (line 296) | inline bool canDelete(uint64_t curEra, tmbase* del) {
type tmtype (line 310) | struct tmtype {
method tmtype (line 316) | tmtype() { }
method tmtype (line 318) | tmtype(T initVal) { pstore(initVal); }
method T (line 343) | T operator->() { return pload(); }
method T (line 361) | T* operator&() {
method isolated_store (line 368) | inline void isolated_store(T newVal) {
method operationsInit (line 373) | inline void operationsInit() {
method resultsInit (line 379) | inline void resultsInit() {
method getSeq (line 385) | inline uint64_t getSeq() const {
method rawStore (line 390) | inline void rawStore(T& newVal, uint64_t lseq) {
class EsLoco (line 423) | class EsLoco {
type block (line 425) | struct block {
method highestBit (line 446) | uint64_t highestBit(uint64_t val) {
method init (line 458) | void init(void* addressOfMemoryPool, size_t sizeOfMemoryPool, bool c...
method reset (line 477) | void reset() {
method getUsedSize (line 483) | uint64_t getUsedSize() {
method free (line 521) | void free(void* ptr) {
type PWriteSetEntry (line 534) | struct PWriteSetEntry {
type PWriteSet (line 541) | struct PWriteSet {
method applyFromRecover (line 547) | void applyFromRecover() {
type PMetadata (line 559) | struct PMetadata {
type WriteSetEntry (line 571) | struct WriteSetEntry {
type WriteSet (line 582) | struct WriteSet {
method WriteSet (line 588) | WriteSet() {
method persistAndFlushLog (line 594) | inline void persistAndFlushLog(PWriteSet* const pwset) {
method flushModifications (line 606) | inline void flushModifications() {
method hash (line 611) | inline uint64_t hash(const void* addr) const {
method addOrReplace (line 616) | inline void addOrReplace(void* addr, uint64_t val) {
method lookupAddr (line 659) | inline uint64_t lookupAddr(const void* addr, uint64_t lval) {
method lookupCacheLine (line 680) | inline bool lookupCacheLine(void* addr, int myidx) {
method WriteSet (line 701) | WriteSet& operator = (const WriteSet &other) {
method apply (line 709) | inline void apply(uint64_t seq, const int tid) {
type OpData (line 723) | struct OpData
type OpData (line 729) | struct OpData {
type AbortedTx (line 738) | struct AbortedTx {}
class OneFileWF (line 741) | class OneFileWF
method OneFileWF (line 776) | OneFileWF() {
method className (line 793) | static std::string className() { return "OneFilePTM-WF"; }
method mapPersistentRegion (line 795) | void mapPersistentRegion(const char* filename, uint8_t* regionAddr, ...
method retireRetiresFromLog (line 856) | void retireRetiresFromLog(OpData& myopd, const int tid) {
method commitTx (line 865) | inline bool commitTx(OpData& myopd, const int tid) {
method innerUpdateTx (line 897) | inline void innerUpdateTx(OpData& myopd, TransFunc* funcptr, const i...
method R (line 934) | static R updateTx(F&& func) {
method updateTx (line 944) | static void updateTx(F&& func) {
method R (line 956) | R readTransaction(F&& func) {
method R (line 990) | static R readTx(F&& func) { return gOFWF.readTransaction<R>(func); }
method readTx (line 991) | static void readTx(F&& func) { gOFWF.readTransaction(func); }
method T (line 993) | static T* tmNew(Args&&... args) {
method tmDelete (line 1001) | static void tmDelete(T* obj) {
method tmFree (line 1017) | static void tmFree(void* obj) {
method pfree (line 1029) | static void pfree(void* obj) {
method T (line 1034) | static inline T* get_object(int idx) {
method put_object (line 1039) | static inline void put_object(int idx, T* obj) {
method helpApply (line 1046) | inline void helpApply(uint64_t lcurTx, const int tid) {
method retireMyFunc (line 1068) | inline void retireMyFunc(const int tid, TransFunc* myfunc, uint64_t ...
method transformAll (line 1077) | inline bool transformAll(const uint64_t lcurrTx, const int tid) {
method recover (line 1097) | void recover() {
class OneFileWF (line 758) | class OneFileWF {
method OneFileWF (line 776) | OneFileWF() {
method className (line 793) | static std::string className() { return "OneFilePTM-WF"; }
method mapPersistentRegion (line 795) | void mapPersistentRegion(const char* filename, uint8_t* regionAddr, ...
method retireRetiresFromLog (line 856) | void retireRetiresFromLog(OpData& myopd, const int tid) {
method commitTx (line 865) | inline bool commitTx(OpData& myopd, const int tid) {
method innerUpdateTx (line 897) | inline void innerUpdateTx(OpData& myopd, TransFunc* funcptr, const i...
method R (line 934) | static R updateTx(F&& func) {
method updateTx (line 944) | static void updateTx(F&& func) {
method R (line 956) | R readTransaction(F&& func) {
method R (line 990) | static R readTx(F&& func) { return gOFWF.readTransaction<R>(func); }
method readTx (line 991) | static void readTx(F&& func) { gOFWF.readTransaction(func); }
method T (line 993) | static T* tmNew(Args&&... args) {
method tmDelete (line 1001) | static void tmDelete(T* obj) {
method tmFree (line 1017) | static void tmFree(void* obj) {
method pfree (line 1029) | static void pfree(void* obj) {
method T (line 1034) | static inline T* get_object(int idx) {
method put_object (line 1039) | static inline void put_object(int idx, T* obj) {
method helpApply (line 1046) | inline void helpApply(uint64_t lcurTx, const int tid) {
method retireMyFunc (line 1068) | inline void retireMyFunc(const int tid, TransFunc* myfunc, uint64_t ...
method transformAll (line 1077) | inline bool transformAll(const uint64_t lcurrTx, const int tid) {
method recover (line 1097) | void recover() {
function R (line 1108) | static R updateTx(F&& func) { return gOFWF.updateTx<R>(func); }
function R (line 1109) | static R readTx(F&& func) { return gOFWF.readTx<R>(func); }
function updateTx (line 1110) | static void updateTx(F&& func) { gOFWF.updateTx(func); }
function readTx (line 1111) | static void readTx(F&& func) { gOFWF.readTx(func); }
function T (line 1112) | T* tmNew(Args&&... args) { return OneFileWF::tmNew<T>(args...); }
function tmDelete (line 1113) | void tmDelete(T* obj) { OneFileWF::tmDelete<T>(obj); }
function T (line 1114) | static T* get_object(int idx) { return OneFileWF::get_object<T>(idx); }
function put_object (line 1115) | static void put_object(int idx, T* obj) { OneFileWF::put_object<T>(idx...
function tmFree (line 1117) | inline void tmFree(void* obj) { OneFileWF::tmFree(obj); }
function T (line 1129) | inline T tmtype<T>::pload() const {
function thread_registry_deregister_thread (line 1175) | void thread_registry_deregister_thread(const int tid) {
FILE: ptms/PMDKTM.hpp
type pmdk (line 14) | namespace pmdk {
class PMDKTM (line 38) | class PMDKTM {
method PMDKTM (line 41) | PMDKTM() {
method className (line 49) | static std::string className() { return "PMDK"; }
method T (line 53) | static inline T* get_object(int idx) {
method put_object (line 58) | static inline void put_object(int idx, T* obj) {
method begin_transaction (line 64) | inline void begin_transaction() {
method end_transaction (line 67) | inline void end_transaction() {
method recover_if_needed (line 70) | inline void recover_if_needed() {
method abort_transaction (line 73) | inline void abort_transaction(void) {
method transaction (line 77) | static void transaction(F&& func) {
method updateTx (line 83) | static void updateTx(F&& func) {
method readTx (line 97) | static void readTx(F&& func) {
method T (line 117) | static T* tmNew(Args&&... args) {
method tmDelete (line 132) | static void tmDelete(T* obj) {
method pfree (line 152) | static void pfree(void* ptr) {
method consistency_check (line 159) | static bool consistency_check(void) {
method R (line 166) | inline static R readTx(F&& func) {
method R (line 171) | inline static R updateTx(F&& func) {
type persist (line 182) | struct persist {
method persist (line 189) | persist() { }
method persist (line 191) | persist(T initVal) {
method T (line 247) | T operator % (const T& rhs) {
method T (line 252) | T operator->() {
method T (line 257) | T* operator&() {
method pstore (line 300) | inline void pstore(T newVal) {
method T (line 304) | inline T pload() const {
FILE: ptms/romuluslog/RomulusLog.cpp
type romuluslog (line 4) | namespace romuluslog {
type stat (line 58) | struct stat
FILE: ptms/romuluslog/RomulusLog.hpp
type romuluslog (line 36) | namespace romuluslog {
class RomulusLog (line 39) | class RomulusLog
type LogEntry (line 98) | struct LogEntry {
type LogChunk (line 103) | struct LogChunk {
type PersistentHeader (line 114) | struct PersistentHeader {
method flush_range (line 148) | inline static void flush_range(uint8_t* addr, size_t length) noexcept {
method apply_pwb (line 162) | inline void apply_pwb(uint8_t* from_addr) {
method apply_log (line 182) | inline void apply_log(uint8_t* from_addr, uint8_t* to_addr) {
method clear_log (line 195) | inline void clear_log() {
method add_to_log (line 215) | inline void add_to_log(void* addr, int length) noexcept {
method className (line 266) | static std::string className() { return "RomulusLog"; }
method T (line 270) | static inline T* get_object(int idx) {
method put_object (line 276) | static inline void put_object(int idx, T* obj) {
method begin_transaction (line 292) | inline void begin_transaction() {
method end_transaction (line 307) | inline void end_transaction() {
method compareMainAndBack (line 337) | bool compareMainAndBack() {
method R (line 375) | R transaction(F&& func) {
method transaction (line 383) | static void transaction(F&& func) {
method ns_write_transaction (line 395) | void ns_write_transaction(Func&& mutativeFunc) {
method ns_read_transaction (line 471) | void ns_read_transaction(Func&& readFunc) {
method begin_read_transaction (line 485) | static void begin_read_transaction() {
method end_read_transaction (line 491) | static void end_read_transaction() {
method T (line 503) | static T* tmNew(Args&&... args) {
method tmDelete (line 528) | static void tmDelete(T* obj) {
method pfree (line 562) | static void pfree(void* ptr) {
method readTx (line 573) | inline static void readTx(F&& func) {
method updateTx (line 578) | inline static void updateTx(F&& func) {
method R (line 585) | inline static R readTx(F&& func) {
method R (line 590) | inline static R updateTx(F&& func) {
method consistency_check (line 600) | static bool consistency_check(void) {
type persist (line 56) | struct persist
method persist (line 623) | persist() { }
method persist (line 625) | persist(T initVal) {
method T (line 676) | T operator % (const T& rhs) {
method T (line 681) | T operator->() {
method T (line 686) | T* operator&() {
method pstore (line 726) | inline void pstore(T newVal) {
method T (line 735) | inline T pload() const {
class RomulusLog (line 70) | class RomulusLog {
type LogEntry (line 98) | struct LogEntry {
type LogChunk (line 103) | struct LogChunk {
type PersistentHeader (line 114) | struct PersistentHeader {
method flush_range (line 148) | inline static void flush_range(uint8_t* addr, size_t length) noexcept {
method apply_pwb (line 162) | inline void apply_pwb(uint8_t* from_addr) {
method apply_log (line 182) | inline void apply_log(uint8_t* from_addr, uint8_t* to_addr) {
method clear_log (line 195) | inline void clear_log() {
method add_to_log (line 215) | inline void add_to_log(void* addr, int length) noexcept {
method className (line 266) | static std::string className() { return "RomulusLog"; }
method T (line 270) | static inline T* get_object(int idx) {
method put_object (line 276) | static inline void put_object(int idx, T* obj) {
method begin_transaction (line 292) | inline void begin_transaction() {
method end_transaction (line 307) | inline void end_transaction() {
method compareMainAndBack (line 337) | bool compareMainAndBack() {
method R (line 375) | R transaction(F&& func) {
method transaction (line 383) | static void transaction(F&& func) {
method ns_write_transaction (line 395) | void ns_write_transaction(Func&& mutativeFunc) {
method ns_read_transaction (line 471) | void ns_read_transaction(Func&& readFunc) {
method begin_read_transaction (line 485) | static void begin_read_transaction() {
method end_read_transaction (line 491) | static void end_read_transaction() {
method T (line 503) | static T* tmNew(Args&&... args) {
method tmDelete (line 528) | static void tmDelete(T* obj) {
method pfree (line 562) | static void pfree(void* ptr) {
method readTx (line 573) | inline static void readTx(F&& func) {
method updateTx (line 578) | inline static void updateTx(F&& func) {
method R (line 585) | inline static R readTx(F&& func) {
method R (line 590) | inline static R updateTx(F&& func) {
method consistency_check (line 600) | static bool consistency_check(void) {
type persist (line 619) | struct persist {
method persist (line 623) | persist() { }
method persist (line 625) | persist(T initVal) {
method T (line 676) | T operator % (const T& rhs) {
method T (line 681) | T operator->() {
method T (line 686) | T* operator&() {
method pstore (line 726) | inline void pstore(T newVal) {
method T (line 735) | inline T pload() const {
FILE: ptms/romuluslog/malloc.cpp
type mallinfo (line 766) | struct mallinfo {
type romuluslog (line 1599) | namespace romuluslog{
function FORCEINLINE (line 1668) | static FORCEINLINE void* win32mmap(size_t size) {
function FORCEINLINE (line 1674) | static FORCEINLINE void* win32direct_mmap(size_t size) {
function FORCEINLINE (line 1681) | static FORCEINLINE int win32munmap(void* ptr, size_t size) {
function FORCEINLINE (line 1834) | static FORCEINLINE int x86_cas_lock(int *sl) {
function FORCEINLINE (line 1845) | static FORCEINLINE void x86_clear_lock(int* sl) {
function spin_acquire_lock (line 1879) | static int spin_acquire_lock(int *sl) {
type malloc_recursive_lock (line 1914) | struct malloc_recursive_lock {
function FORCEINLINE (line 1923) | static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) {
function FORCEINLINE (line 1930) | static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) {
function FORCEINLINE (line 1951) | static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) {
function init_malloc_global_mutex (line 1987) | static void init_malloc_global_mutex() {
function pthread_init_lock (line 2022) | static int pthread_init_lock (MLOCK_T *lk) {
type malloc_chunk (line 2185) | struct malloc_chunk {
type malloc_chunk (line 2188) | struct malloc_chunk
type malloc_chunk (line 2189) | struct malloc_chunk
type malloc_chunk (line 2192) | struct malloc_chunk
type malloc_chunk (line 2188) | struct malloc_chunk
type malloc_chunk (line 2189) | struct malloc_chunk
type malloc_chunk (line 2193) | struct malloc_chunk
type malloc_chunk (line 2188) | struct malloc_chunk
type malloc_chunk (line 2189) | struct malloc_chunk
type malloc_chunk (line 2194) | struct malloc_chunk
type malloc_chunk (line 2188) | struct malloc_chunk
type malloc_chunk (line 2189) | struct malloc_chunk
type malloc_tree_chunk (line 2394) | struct malloc_tree_chunk {
type malloc_tree_chunk (line 2398) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2399) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2401) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2402) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2406) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2398) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2399) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2401) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2402) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2407) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2398) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2399) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2401) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2402) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2408) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2398) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2399) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2401) | struct malloc_tree_chunk
type malloc_tree_chunk (line 2402) | struct malloc_tree_chunk
type malloc_segment (line 2470) | struct malloc_segment {
type malloc_segment (line 2473) | struct malloc_segment
type malloc_segment (line 2480) | struct malloc_segment
type malloc_segment (line 2473) | struct malloc_segment
type malloc_segment (line 2481) | struct malloc_segment
type malloc_segment (line 2473) | struct malloc_segment
type malloc_state (line 2580) | struct malloc_state {
type malloc_state (line 2605) | struct malloc_state
type malloc_params (line 2616) | struct malloc_params {
type malloc_params (line 2625) | struct malloc_params
type malloc_state (line 2633) | struct malloc_state
function msegmentptr (line 2699) | static msegmentptr segment_holding(mstate m, char* addr) {
function has_segment_link (line 2710) | static int has_segment_link(mstate m, msegmentptr ss) {
function pre_fork (line 3094) | static void pre_fork(void) { ACQUIRE_LOCK(&(gm)->mutex); }
function post_fork_parent (line 3095) | static void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); }
function post_fork_child (line 3096) | static void post_fork_child(void) { INITIAL_LOCK(&(gm)->mutex); }
function init_mparams (line 3100) | static int init_mparams(void) {
function change_mparam (line 3190) | static int change_mparam(int param_number, int value) {
function do_check_any_chunk (line 3217) | static void do_check_any_chunk(mstate m, mchunkptr p) {
function do_check_top_chunk (line 3223) | static void do_check_top_chunk(mstate m, mchunkptr p) {
function do_check_mmapped_chunk (line 3237) | static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
function do_check_inuse_chunk (line 3251) | static void do_check_inuse_chunk(mstate m, mchunkptr p) {
function do_check_free_chunk (line 3262) | static void do_check_free_chunk(mstate m, mchunkptr p) {
function do_check_malloced_chunk (line 3285) | static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
function do_check_tree (line 3299) | static void do_check_tree(mstate m, tchunkptr t) {
function do_check_treebin (line 3350) | static void do_check_treebin(mstate m, bindex_t i) {
function do_check_smallbin (line 3361) | static void do_check_smallbin(mstate m, bindex_t i) {
function bin_find (line 3385) | static int bin_find(mstate m, mchunkptr x) {
function traverse_and_check (line 3421) | static size_t traverse_and_check(mstate m) {
function do_check_malloc_state (line 3453) | static void do_check_malloc_state(mstate m) {
function internal_mallinfo (line 3485) | static struct mallinfo internal_mallinfo(mstate m) {
function internal_malloc_stats (line 3526) | static void internal_malloc_stats(mstate m) {
function mchunkptr (line 3856) | static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int ...
function init_top (line 3894) | static void init_top(mstate m, mchunkptr p, size_t psize) {
function init_bins (line 3909) | static void init_bins(mstate m) {
function reset_on_error (line 3921) | static void reset_on_error(mstate m) {
function add_segment (line 3980) | static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mm...
function release_unused_segments (line 4246) | static size_t release_unused_segments(mstate m) {
function sys_trim (line 4293) | static int sys_trim(mstate m, size_t pad) {
function dispose_chunk (line 4361) | static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {
function dlfree (line 4680) | void dlfree(void* mem) {
function mchunkptr (line 4809) | static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
function internal_bulk_free (line 5095) | static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) {
function internal_inspect_all (line 5139) | static void internal_inspect_all(mstate m,
function dlposix_memalign (line 5266) | int dlposix_memalign(void** pp, size_t alignment, size_t bytes) {
function dlbulk_free (line 5314) | size_t dlbulk_free(void* array[], size_t nelem) {
function dlmalloc_inspect_all (line 5319) | void dlmalloc_inspect_all(void(*handler)(void *start,
function dlmalloc_trim (line 5332) | int dlmalloc_trim(size_t pad) {
function dlmalloc_footprint (line 5342) | size_t dlmalloc_footprint(void) {
function dlmalloc_max_footprint (line 5346) | size_t dlmalloc_max_footprint(void) {
function dlmalloc_footprint_limit (line 5350) | size_t dlmalloc_footprint_limit(void) {
function dlmalloc_set_footprint_limit (line 5355) | size_t dlmalloc_set_footprint_limit(size_t bytes) {
function dlmallinfo (line 5367) | struct mallinfo dlmallinfo(void) {
function dlmalloc_stats (line 5373) | void dlmalloc_stats() {
function dlmallopt (line 5378) | int dlmallopt(int param_number, int value) {
function dlmalloc_usable_size (line 5382) | size_t dlmalloc_usable_size(void* mem) {
function mstate (line 5397) | static mstate init_user_mstate(char* tbase, size_t tsize) {
function mspace (line 5420) | mspace create_mspace(size_t capacity, int locked) {
function mspace (line 5439) | mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
function mspace_track_large_chunks (line 5453) | int mspace_track_large_chunks(mspace msp, int enable) {
function destroy_mspace (line 5470) | size_t destroy_mspace(mspace msp) {
function mspace_free (line 5612) | void mspace_free(mspace msp, void* mem) {
function mspace_bulk_free (line 5843) | size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) {
function mspace_inspect_all (line 5848) | void mspace_inspect_all(mspace msp,
function mspace_trim (line 5867) | int mspace_trim(mspace msp, size_t pad) {
function mspace_malloc_stats (line 5883) | void mspace_malloc_stats(mspace msp) {
function mspace_footprint (line 5894) | size_t mspace_footprint(mspace msp) {
function mspace_max_footprint (line 5906) | size_t mspace_max_footprint(mspace msp) {
function mspace_footprint_limit (line 5918) | size_t mspace_footprint_limit(mspace msp) {
function mspace_set_footprint_limit (line 5931) | size_t mspace_set_footprint_limit(mspace msp, size_t bytes) {
function mspace_mallinfo (line 5950) | struct mallinfo mspace_mallinfo(mspace msp) {
function mspace_usable_size (line 5959) | size_t mspace_usable_size(const void* mem) {
function mspace_mallopt (line 5968) | int mspace_mallopt(int param_number, int value) {
FILE: ptms/romuluslr/RomulusLR.cpp
type romuluslr (line 5) | namespace romuluslr{
FILE: ptms/romuluslr/RomulusLR.hpp
type romuluslr (line 59) | namespace romuluslr {
class RIStaticPerThread (line 66) | class RIStaticPerThread {
method RIStaticPerThread (line 76) | RIStaticPerThread(int maxThreads) : maxThreads{maxThreads} {
method arrive (line 87) | inline void arrive(const int tid) noexcept {
method depart (line 91) | inline void depart(const int tid) noexcept {
method isEmpty (line 95) | inline bool isEmpty() noexcept {
class RomulusLR (line 105) | class RomulusLR
type LogEntry (line 152) | struct LogEntry {
type
Condensed preview — 412 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,909K chars).
[
{
"path": "LICENSE.txt",
"chars": 1210,
"preview": "Copyright (c) 2017-2018\n Andreia Correia <andreia.veiga@unine.ch>\n Pedro Ramalhete <pramalhe@gmail.com>\n Pascal Felbe"
},
{
"path": "README.md",
"chars": 12718,
"preview": "\n# OneFile PTM / STM\n\nOneFile is a Software Transactional Memory (STM) meant to make it easy to implement lock-free and "
},
{
"path": "common/HazardEras.hpp",
"chars": 7034,
"preview": "/******************************************************************************\r\n * Copyright (c) 2016-2017, Pedro Ramal"
},
{
"path": "common/HazardPointers.hpp",
"chars": 8224,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "common/HazardPointersSimQueue.hpp",
"chars": 6432,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "common/README.md",
"chars": 744,
"preview": "Here are some files that are needed by other libraries and data structures:\r\n\r\n HazardEras.hpp Used by s"
},
{
"path": "common/RIStaticPerThread.hpp",
"chars": 3866,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "common/ThreadRegistry.cpp",
"chars": 564,
"preview": "/*\r\n * Contains all global variables.\r\n */\r\n#include \"common/ThreadRegistry.hpp\"\r\n\r\n// Global/singleton to hold all the "
},
{
"path": "common/ThreadRegistry.hpp",
"chars": 3367,
"preview": "#ifndef _THREAD_REGISTRY_H_\r\n#define _THREAD_REGISTRY_H_\r\n\r\n#include <atomic>\r\n#include <thread>\r\n#include <iostream>\r\n#"
},
{
"path": "common/pfences.h",
"chars": 5279,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/generic/TMHashMap.hpp",
"chars": 8318,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/generic/TMLinkedListQueue.hpp",
"chars": 4388,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2017, Pedro Ramal"
},
{
"path": "datastructures/generic/TMLinkedListSet.hpp",
"chars": 8483,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/generic/TMRedBlackBST.hpp",
"chars": 22789,
"preview": "#ifndef _TM_RED_BLACK_BST_H_\r\n#define _TM_RED_BLACK_BST_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#include <algori"
},
{
"path": "datastructures/hashmaps/CRWWPSTMResizableHashSet.hpp",
"chars": 5636,
"preview": "/*\n * Copyright 2017-2018\n * Andreia Correia <andreia.veiga@unine.ch>\n * Pedro Ramalhete <pramalhe@gmail.com>\n * P"
},
{
"path": "datastructures/hashmaps/ESTMResizableHashSet.hpp",
"chars": 5520,
"preview": "/*\n * Copyright 2017-2018\n * Andreia Correia <andreia.veiga@unine.ch>\n * Pedro Ramalhete <pramalhe@gmail.com>\n * P"
},
{
"path": "datastructures/hashmaps/OFLFResizableHashSet.hpp",
"chars": 5545,
"preview": "/*\n * Copyright 2017-2018\n * Andreia Correia <andreia.veiga@unine.ch>\n * Pedro Ramalhete <pramalhe@gmail.com>\n * P"
},
{
"path": "datastructures/hashmaps/OFWFResizableHashSet.hpp",
"chars": 5545,
"preview": "/*\n * Copyright 2017-2018\n * Andreia Correia <andreia.veiga@unine.ch>\n * Pedro Ramalhete <pramalhe@gmail.com>\n * P"
},
{
"path": "datastructures/hashmaps/TinySTMResizableHashSet.hpp",
"chars": 5670,
"preview": "/*\n * Copyright 2017-2018\n * Andreia Correia <andreia.veiga@unine.ch>\n * Pedro Ramalhete <pramalhe@gmail.com>\n * P"
},
{
"path": "datastructures/linkedlists/CRWWPLinkedListSet.hpp",
"chars": 5565,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/linkedlists/ESTMLinkedListSet.hpp",
"chars": 4234,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/linkedlists/HazardEras.hpp",
"chars": 7242,
"preview": "/******************************************************************************\r\n * Copyright (c) 2016-2017, Pedro Ramal"
},
{
"path": "datastructures/linkedlists/HazardPointers.hpp",
"chars": 6189,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2017, Pedro Ramal"
},
{
"path": "datastructures/linkedlists/MagedHarrisLinkedListSetHE.hpp",
"chars": 9402,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/linkedlists/MagedHarrisLinkedListSetHP.hpp",
"chars": 9560,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/linkedlists/OFLFLinkedListSet.hpp",
"chars": 4226,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/linkedlists/OFWFLinkedListSet.hpp",
"chars": 4203,
"preview": " /*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n "
},
{
"path": "datastructures/linkedlists/STMLinkedListSet.hpp",
"chars": 5811,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/linkedlists/TinySTMLinkedListSet.hpp",
"chars": 4399,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/queues/CRWWPLinkedListQueue.hpp",
"chars": 4110,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2017, Pedro Ramal"
},
{
"path": "datastructures/queues/ESTMArrayLinkedListQueue.hpp",
"chars": 5195,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2017, Pedro Ramal"
},
{
"path": "datastructures/queues/ESTMLinkedListQueue.hpp",
"chars": 3873,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/queues/FAAArrayQueue.hpp",
"chars": 8066,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/queues/HazardPointers.hpp",
"chars": 6495,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/queues/HazardPointersSimQueue.hpp",
"chars": 6117,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/queues/LCRQueue.hpp",
"chars": 11928,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/queues/MichaelScottQueue.hpp",
"chars": 5758,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/queues/OFLFArrayLinkedListQueue.hpp",
"chars": 3646,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/queues/OFLFArrayQueue.hpp",
"chars": 1900,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/queues/OFLFLinkedListQueue.hpp",
"chars": 2513,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/queues/OFWFArrayLinkedListQueue.hpp",
"chars": 3418,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/queues/OFWFLinkedListQueue.hpp",
"chars": 2538,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "datastructures/queues/README.md",
"chars": 853,
"preview": "# Queues #\r\n\r\nThis folder contains multiple multi-producer-multi-consumer queue implementations, all of them with integr"
},
{
"path": "datastructures/queues/SimQueue.hpp",
"chars": 12139,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/queues/TinySTMArrayLinkedListQueue.hpp",
"chars": 4792,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2017, Pedro Ramal"
},
{
"path": "datastructures/queues/TinySTMLinkedListQueue.hpp",
"chars": 3831,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/queues/TurnQueue.hpp",
"chars": 10753,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/sequential/HashSet.hpp",
"chars": 2954,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2018, Pedro Ramal"
},
{
"path": "datastructures/sequential/LinkedListQueue.hpp",
"chars": 3616,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2017, Pedro Ramal"
},
{
"path": "datastructures/sequential/LinkedListSet.hpp",
"chars": 3225,
"preview": "#ifndef _SEQUENTIAL_LINKED_LIST_SET_H_\r\n#define _SEQUENTIAL_LINKED_LIST_SET_H_\r\n\r\n#include <string>\r\n\r\n/**\r\n * <h1> A se"
},
{
"path": "datastructures/sequential/RedBlackBST.hpp",
"chars": 21585,
"preview": "#ifndef _RED_BLACK_BST_H_\r\n#define _RED_BLACK_BST_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#include <algorithm>\r\n"
},
{
"path": "datastructures/sequential/SortedArraySet.hpp",
"chars": 6300,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/sequential/SortedVectorSet.hpp",
"chars": 5230,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/sequential/TreeSet.hpp",
"chars": 3332,
"preview": "/******************************************************************************\r\n * Copyright (c) 2014-2016, Pedro Ramal"
},
{
"path": "datastructures/treemaps/ESTMRedBlackTree.hpp",
"chars": 22693,
"preview": "#ifndef _ESTM_RED_BLACK_BST_H_\r\n#define _ESTM_RED_BLACK_BST_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#include <al"
},
{
"path": "datastructures/treemaps/HazardEras.hpp",
"chars": 7242,
"preview": "/******************************************************************************\r\n * Copyright (c) 2016-2017, Pedro Ramal"
},
{
"path": "datastructures/treemaps/NatarajanTreeHE.hpp",
"chars": 20495,
"preview": "/*\r\n\r\nCopyright 2017 University of Rochester\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may"
},
{
"path": "datastructures/treemaps/OFLFRedBlackTree.hpp",
"chars": 22516,
"preview": "#ifndef _OF_LF_RED_BLACK_BST_H_\r\n#define _OF_LF_RED_BLACK_BST_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#include <"
},
{
"path": "datastructures/treemaps/OFWFRedBlackTree.hpp",
"chars": 22302,
"preview": "#ifndef _OF_WF_RED_BLACK_BST_H_\r\n#define _OF_WF_RED_BLACK_BST_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#include <"
},
{
"path": "datastructures/treemaps/TinySTMRedBlackTree.hpp",
"chars": 22665,
"preview": "#ifndef _TINY_STM_RED_BLACK_BST_H_\r\n#define _TINY_STM_RED_BLACK_BST_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#inc"
},
{
"path": "datastructures/trevor_brown_abtree/Makefile",
"chars": 452,
"preview": "GPP = g++\nFLAGS = -std=c++11 -mcx16 -O3 -g\nFLAGS += -DPHYSICAL_PROCESSORS=48 -DMAX_TID_POW2=64\n\nLDFLAGS += -I./common\nLD"
},
{
"path": "datastructures/trevor_brown_abtree/TrevorBrownABTree.hpp",
"chars": 2462,
"preview": "#ifndef _TREVOR_BROWN_AB_TREE_HP_H_\r\n#define _TREVOR_BROWN_AB_TREE_HP_H_\r\n\r\n#include <cassert>\r\n#include <stdexcept>\r\n#i"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/generalize-small.h",
"chars": 64924,
"preview": "/* char_load */\r\n#if defined(AO_HAVE_char_load_acquire) && !defined(AO_HAVE_char_load)\r\n# define AO_char_load(addr) AO_"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/generalize.h",
"chars": 50260,
"preview": "/*\r\n * Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of c"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/README",
"chars": 360,
"preview": "There are two kinds of entities in this directory:\r\n\r\n- Subdirectories corresponding to specific compilers (or compiler/"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/acquire_release_volatile.h",
"chars": 2378,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/aligned_atomic_load_store.h",
"chars": 1761,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/all_acquire_release_volatile.h",
"chars": 1544,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n * \r\n * Permission is hereby granted, free of charg"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/all_aligned_atomic_load_store.h",
"chars": 1507,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/all_atomic_load_store.h",
"chars": 1483,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ao_t_is_int.h",
"chars": 5474,
"preview": "/*\r\n * Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of c"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/armcc/arm_v6.h",
"chars": 7042,
"preview": "/*\r\n * Copyright (c) 2007 by NEC LE-IT: All rights reserved.\r\n * A transcription of ARMv6 atomic operation"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/atomic_load_store.h",
"chars": 1664,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/char_acquire_release_volatile.h",
"chars": 2057,
"preview": "/*\r\n * Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of c"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/char_atomic_load_store.h",
"chars": 1755,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/emul_cas.h",
"chars": 3132,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n * \r\n * Permission is hereby granted, free "
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/alpha.h",
"chars": 2045,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/arm.h",
"chars": 10132,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/avr32.h",
"chars": 2362,
"preview": "/*\r\n * Copyright (C) 2009 Bradley Smith <brad@brad-smith.co.uk>\r\n *\r\n * Permission is hereby granted, free of charge, to"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/cris.h",
"chars": 2947,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n * \r\n * Permission is hereby granted, free of charg"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/hppa.h",
"chars": 4288,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/ia64.h",
"chars": 9740,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/m68k.h",
"chars": 2239,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/mips.h",
"chars": 3214,
"preview": "/*\r\n * Copyright (c) 2005,2007 Thiemo Seufer <ths@networkno.de>\r\n *\r\n * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTEL"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/powerpc.h",
"chars": 11170,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/s390.h",
"chars": 2610,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/sh.h",
"chars": 993,
"preview": "/*\r\n * Copyright (c) 2009 by Takashi YOSHII. All rights reserved.\r\n *\r\n *\r\n * THIS MATERIAL IS PROVIDED AS IS, WITH ABSO"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/sparc.h",
"chars": 2787,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/x86.h",
"chars": 6154,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/gcc/x86_64.h",
"chars": 6517,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/generic_pthread.h",
"chars": 7490,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/hpc/hppa.h",
"chars": 4331,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/hpc/ia64.h",
"chars": 5375,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ibmc/powerpc.h",
"chars": 3923,
"preview": "/* FIXME. This is only a placeholder for the AIX compiler. */\r\n/* It doesn't work. Please send a patch. "
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/icc/ia64.h",
"chars": 6480,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/int_acquire_release_volatile.h",
"chars": 2048,
"preview": "/*\r\n * Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of c"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/int_aligned_atomic_load_store.h",
"chars": 1852,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/int_atomic_load_store.h",
"chars": 1744,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/arm.h",
"chars": 3445,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/common32_defs.h",
"chars": 4551,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/x86.h",
"chars": 4580,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/msftc/x86_64.h",
"chars": 5658,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ordered.h",
"chars": 1414,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/ordered_except_wr.h",
"chars": 3121,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/read_ordered.h",
"chars": 2915,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/short_acquire_release_volatile.h",
"chars": 2068,
"preview": "/*\r\n * Copyright (c) 2003-2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of c"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/short_aligned_atomic_load_store.h",
"chars": 1878,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/short_atomic_load_store.h",
"chars": 1766,
"preview": "/*\r\n * Copyright (c) 2003 by Hewlett-Packard Company. All rights reserved.\r\n *\r\n * Permission is hereby granted, free o"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/standard_ao_double_t.h",
"chars": 848,
"preview": "/* NEC LE-IT: For 64Bit OS we extend the double type to hold two int64's\r\n*\r\n* x86-64: __m128 serves as placeholder whi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/sunc/sparc.h",
"chars": 1646,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n * \r\n * Permission is hereby granted, free of charg"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/sunc/x86.h",
"chars": 6025,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/sunc/x86_64.h",
"chars": 6477,
"preview": "/*\r\n * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.\r\n * Copyright (c) 1996-1999 by Silicon Graphi"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/test_and_set_t_is_ao_t.h",
"chars": 1664,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops/sysdeps/test_and_set_t_is_char.h",
"chars": 1626,
"preview": "/*\r\n * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.\r\n * \r\n * Permission is hereby granted, free of charg"
},
{
"path": "datastructures/trevor_brown_abtree/common/atomic_ops/atomic_ops.h",
"chars": 17126,
"preview": "/*\r\n * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.\r\n *\r\n * Permission is hereby granted, free of charge"
},
{
"path": "datastructures/trevor_brown_abtree/common/dcss/dcss_plus.h",
"chars": 4167,
"preview": "/* \r\n * File: dcss_plus.h\r\n * Author: Maya Arbel-Raviv\r\n *\r\n * Created on May 1, 2017, 10:42 AM\r\n */\r\n\r\n#ifndef DCSS_P"
},
{
"path": "datastructures/trevor_brown_abtree/common/dcss/dcss_plus_impl.h",
"chars": 9750,
"preview": "/* \r\n * File: dcss_plus_impl.h\r\n * Author: Maya Arbel-Raviv\r\n *\r\n * Created on May 1, 2017, 10:52 AM\r\n */\r\n\r\n#ifndef D"
},
{
"path": "datastructures/trevor_brown_abtree/common/dcss/testing.cpp",
"chars": 6358,
"preview": "#include <cstdlib>\r\n#include <cmath>\r\n#include <iostream>\r\n#include \"dcss_plus_impl.h\"\r\n\r\nusing namespace std;\r\n\r\n#defin"
},
{
"path": "datastructures/trevor_brown_abtree/common/descriptors/descriptors.h",
"chars": 237,
"preview": "/* \r\n * File: descriptors.h\r\n * Author: tabrown\r\n *\r\n * Created on June 8, 2016, 6:18 PM\r\n */\r\n\r\n#ifndef DESCRIPTORS_H"
},
{
"path": "datastructures/trevor_brown_abtree/common/descriptors/descriptors_impl.h",
"chars": 4781,
"preview": "/* \r\n * File: descriptors_impl.h\r\n * Author: tabrown\r\n *\r\n * Created on June 9, 2016, 4:04 PM\r\n */\r\n\r\n#ifndef DESCRIPT"
},
{
"path": "datastructures/trevor_brown_abtree/common/descriptors/descriptors_impl2.h",
"chars": 7046,
"preview": "/* \r\n * File: descriptors_impl2.h\r\n * Author: tabrown\r\n *\r\n * Created on June 30, 2016, 11:53 AM\r\n */\r\n\r\n#ifndef DESCR"
},
{
"path": "datastructures/trevor_brown_abtree/common/errors.h",
"chars": 608,
"preview": "/* \r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n *\r\n * Created on April 20, 2017, 1:09 PM\r\n */\r\n"
},
{
"path": "datastructures/trevor_brown_abtree/common/plaf.h",
"chars": 766,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/allocator_bump.h",
"chars": 6411,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/allocator_interface.h",
"chars": 1181,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/allocator_new.h",
"chars": 2674,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/allocator_new_segregated.h",
"chars": 3995,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/allocator_once.h",
"chars": 5938,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/arraylist.h",
"chars": 4146,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/blockbag.h",
"chars": 28418,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/blockpool.h",
"chars": 2424,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/debug_info.h",
"chars": 3856,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/debugcounter.h",
"chars": 1260,
"preview": "/* \r\n * File: debugcounter.h\r\n * Author: trbot\r\n *\r\n * Created on September 27, 2015, 4:43 PM\r\n */\r\n\r\n#ifndef DEBUGCOU"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/debugprinting.h",
"chars": 970,
"preview": "/* \r\n * File: debugprinting.h\r\n * Author: trbot\r\n *\r\n * Created on June 24, 2016, 12:49 PM\r\n */\r\n\r\n#ifndef DEBUGPRINTI"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/globals.h",
"chars": 946,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/hashtable.h",
"chars": 7837,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/lockfreeblockbag.h",
"chars": 3636,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/pool_interface.h",
"chars": 2113,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/pool_none.h",
"chars": 2383,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/pool_perthread_and_shared.h",
"chars": 6064,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_debra.h",
"chars": 15155,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_debraplus.h",
"chars": 20371,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_hazardptr.h",
"chars": 13131,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_interface.h",
"chars": 3450,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_none.h",
"chars": 3406,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/reclaimer_rcu.h",
"chars": 7339,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/record_manager.h",
"chars": 11806,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/record_manager_single_type.h",
"chars": 7561,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/recordmgr/recovery_manager.h",
"chars": 7970,
"preview": "/**\r\n * C++ record manager implementation (PODC 2015) by Trevor Brown.\r\n * \r\n * Copyright (C) 2015 Trevor Brown\r\n *\r\n */"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_dcssp.h",
"chars": 42411,
"preview": "/* \r\n * File: rq_dcssp.h\r\n * Author: trbot\r\n *\r\n * Created on May 9, 2017, 4:30 PM\r\n */\r\n\r\n#ifndef RQ_DCSSP_H\r\n#define"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_debugging.h",
"chars": 12873,
"preview": "/* \r\n * File: rq_debugging.h\r\n * Author: trbot\r\n *\r\n * Created on May 15, 2017, 5:23 PM\r\n */\r\n\r\n#ifndef RQ_DEBUGGING_H"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_htm_rwlock.h",
"chars": 24848,
"preview": "/* \r\n * File: rq_rwlock.h\r\n * Author: trbot\r\n *\r\n * Created on April 20, 2017, 1:03 PM\r\n */\r\n\r\n#ifndef RQ_RWLOCK_H\r\n#d"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_provider.h",
"chars": 692,
"preview": "/* \r\n * File: rq_provider.h\r\n * Author: trbot\r\n *\r\n * Created on May 16, 2017, 5:14 PM\r\n */\r\n\r\n#ifndef RQ_PROVIDER_H\r\n"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_rwlock.h",
"chars": 22958,
"preview": "/* \r\n * File: rq_rwlock.h\r\n * Author: trbot\r\n *\r\n * Created on April 20, 2017, 1:03 PM\r\n */\r\n\r\n#ifndef RQ_RWLOCK_H\r\n#d"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_snapcollector.h",
"chars": 13618,
"preview": "/* \r\n * File: rq_rwlock.h\r\n * Author: trbot\r\n *\r\n * Created on April 20, 2017, 1:03 PM\r\n * \r\n * Implementation of Shah"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/rq_unsafe.h",
"chars": 8624,
"preview": "/* \r\n * File: rq_unsafe.h\r\n * Author: trbot\r\n *\r\n * Created on May 15, 2017, 5:06 PM\r\n */\r\n\r\n#ifndef RQ_UNSAFE_H\r\n#def"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/snapcollector/reportitem.h",
"chars": 1252,
"preview": "/* \r\n * File: reportitem.h\r\n * Author: trbot\r\n *\r\n * Created on June 21, 2017, 4:47 PM\r\n */\r\n\r\n#ifndef REPORTITEM_H\r\n#"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/snapcollector/snapcollector.h",
"chars": 17945,
"preview": "/* \r\n * File: snapcollector.h\r\n * Author: trbot\r\n *\r\n * Created on June 21, 2017, 4:57 PM\r\n */\r\n\r\n#ifndef SNAPCOLLECTO"
},
{
"path": "datastructures/trevor_brown_abtree/common/rq/snapcollector/snapcollector_test.cpp",
"chars": 1299,
"preview": "/* \r\n * File: test.cpp\r\n * Author: trbot\r\n *\r\n * Created on June 21, 2017, 5:25 PM\r\n */\r\n\r\n#include <iostream>\r\n#inclu"
},
{
"path": "datastructures/trevor_brown_abtree/common/rwlock.h",
"chars": 3928,
"preview": "/* \r\n * File: rwlock.h\r\n * Author: trbot\r\n *\r\n * Created on June 29, 2017, 8:25 PM\r\n */\r\n\r\n#ifndef RWLOCK_H\r\n#define R"
},
{
"path": "datastructures/trevor_brown_abtree/ds/brown_ext_abtree_lf/brown_ext_abtree_lf.h",
"chars": 22859,
"preview": "/**\r\n * Implementation of the dictionary ADT with a lock-free relaxed (a,b)-tree.\r\n * Copyright (C) 2016 Trevor Brown\r\n "
},
{
"path": "datastructures/trevor_brown_abtree/ds/brown_ext_abtree_lf/brown_ext_abtree_lf_adapter.h",
"chars": 2569,
"preview": "/* \r\n * File: bst_adapter.h\r\n * Author: trbot\r\n *\r\n * Created on August 31, 2017, 6:53 PM\r\n */\r\n\r\n#ifndef BST_ADAPTER_"
},
{
"path": "datastructures/trevor_brown_abtree/ds/brown_ext_abtree_lf/brown_ext_abtree_lf_impl.h",
"chars": 54253,
"preview": "/**\r\n * Implementation of the dictionary ADT with a lock-free relaxed (a,b)-tree.\r\n * Copyright (C) 2016 Trevor Brown\r\n "
},
{
"path": "datastructures/trevor_brown_abtree/minimal_example.cpp",
"chars": 1591,
"preview": "/**\r\n * Author: Trevor Brown (me [at] tbrown [dot] pro).\r\n * Copyright 2018.\r\n * \r\n * This program is free software; you"
},
{
"path": "datastructures/trevor_brown_natarajan/TrevorBrownNatarajanTree.hpp",
"chars": 2597,
"preview": "#ifndef _TREVOR_BROWN_NATARAJAN_TREE_HP_H_\r\n#define _TREVOR_BROWN_NATARAJAN_TREE_HP_H_\r\n\r\n#include <cassert>\r\n#include <"
},
{
"path": "datastructures/trevor_brown_natarajan/ds/natarajan_ext_bst_lf/natarajan_ext_bst_lf_adapter.h",
"chars": 3317,
"preview": "/* \r\n * Implementation of the lock-free tree of Natarajan and Mittal.\r\n * \r\n * Heavily edited by Trevor Brown (me [at] t"
},
{
"path": "datastructures/trevor_brown_natarajan/ds/natarajan_ext_bst_lf/natarajan_ext_bst_lf_stage1.h",
"chars": 10196,
"preview": "/*A Lock Free Binary Search Tree\r\n \r\n * File:\r\n * wfrbt.cpp\r\n * Author(s):\r\n * Aravind Natarajan <natarajan.aravind@"
},
{
"path": "datastructures/trevor_brown_natarajan/ds/natarajan_ext_bst_lf/natarajan_ext_bst_lf_stage2_impl.h",
"chars": 23636,
"preview": "/*A Lock Free Binary Search Tree\r\n \r\n * File:\r\n * wfrbt.cpp\r\n * Author(s):\r\n * Aravind Natarajan <natarajan.aravind@"
},
{
"path": "graphs/BenchmarkLatencyCounter.hpp",
"chars": 8729,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/BenchmarkLatencyQueues.hpp",
"chars": 12588,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/BenchmarkMaps.hpp",
"chars": 8626,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/BenchmarkQueues.hpp",
"chars": 11716,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/BenchmarkSPS.hpp",
"chars": 10883,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/BenchmarkSets.hpp",
"chars": 13122,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/Makefile",
"chars": 14313,
"preview": "CXX = g++-8\nCXXFLAGS = -std=c++17 -g -O2 -DPWB_IS_CLFLUSHOPT # -fuse-ld=gold -fsanitize=address\n# For castor-1\n#CXXFLAGS"
},
{
"path": "graphs/PBenchmarkQueues.hpp",
"chars": 14701,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/PBenchmarkSPS.hpp",
"chars": 7073,
"preview": "/*\r\n * Copyright 2017-2018\r\n * Andreia Correia <andreia.veiga@unine.ch>\r\n * Pedro Ramalhete <pramalhe@gmail.com>\r\n *"
},
{
"path": "graphs/PBenchmarkSets.hpp",
"chars": 9178,
"preview": "/*\n * Copyright 2017-2018\n * Andreia Correia <andreia.veiga@unine.ch>\n * Pedro Ramalhete <pramalhe@gmail.com>\n * P"
},
{
"path": "graphs/README.md",
"chars": 308,
"preview": "Every .cpp file here outputs a plot taken from a benchmark.\r\nThe corresponding tab-separated values are placed in the da"
},
{
"path": "graphs/bin/.gitignore",
"chars": 734,
"preview": "/pset-ll-1k\n/psps-integer\n/q-array-enq-deq\n/q-ll-burst\n/q-ll-enq-deq\n/q-ll-enq-deq-tiny\n/set-hash-1k-tiny\n/set-ll-10k\n/s"
},
{
"path": "graphs/data/README.md",
"chars": 38,
"preview": "The benchmarks will generate data here"
},
{
"path": "graphs/latency-counter.cpp",
"chars": 2926,
"preview": "#include <iostream>\r\n#include <fstream>\r\n#include <cstring>\r\n#include \"BenchmarkLatencyCounter.hpp\"\r\n#include \"stms/OneF"
},
{
"path": "graphs/lib/.gitignore",
"chars": 82,
"preview": "/libromulus.a\n/mallocromlog.o\n/mallocromlr.o\n/romlog.o\n/romlr.o\n/threadregistry.o\n"
},
{
"path": "graphs/plots/caption.gp",
"chars": 718,
"preview": "set term postscript color eps enhanced 22\nset output \"caption.eps\"\n\nset size 0.95,0.15\n\nload \"styles.inc\"\n\nunset tics\nun"
},
{
"path": "graphs/plots/latency-counter.gp",
"chars": 4355,
"preview": "set term postscript color eps enhanced 22\nset output \"latency-counter.eps\"\n\nset size 0.95,1.12\n\nX=0.1\nW=0.26\nM=0.025\n\nlo"
},
{
"path": "graphs/plots/pcaption.gp",
"chars": 790,
"preview": "set term postscript color eps enhanced 22\nset output \"pcaption.eps\"\n\nset size 0.95,0.15\n\nload \"styles.inc\"\n\nunset tics\nu"
},
{
"path": "graphs/plots/plot-all.sh",
"chars": 381,
"preview": "#!/bin/sh\n\nfor i in \\\ncaption.gp \\\nsps-integer.gp \\\nsps-object.gp \\\nq-enq-deq.gp \\\nset-ll-1k.gp \\\nset-hash-1k.gp \\\nset-t"
},
{
"path": "graphs/plots/plot.sh",
"chars": 172,
"preview": "#!/bin/sh\n\nwhile [ $# -gt 0 ]\ndo\n echo \"Processing:\" $1\n gnuplot $1\n epstopdf `basename $1 .gp`.eps\n rm `basename $1"
},
{
"path": "graphs/plots/pq-enq-deq.gp",
"chars": 2149,
"preview": "set term postscript color eps enhanced 22\nset output \"pq-enq-deq.eps\"\n\nset size 0.95,0.6\n\nX=0.08\nW=0.370\nM=0.100\n\nload \""
},
{
"path": "graphs/plots/pq-ll-enq-deq.gp",
"chars": 1328,
"preview": "set term postscript color eps enhanced 22\nset output \"pq-ll-enq-deq.eps\"\n\nset size 0.95,0.6\n\nS=0.2125\nX=0.1\nW=0.375\nM=0."
},
{
"path": "graphs/plots/pset-hash-1k.gp",
"chars": 5175,
"preview": "set term postscript color eps enhanced 22\nset output \"pset-hash-1k.eps\"\n\nset size 0.95,1.12\n\nX=0.1\nW=0.26\nM=0.025\n\nload "
},
{
"path": "graphs/plots/pset-ll-1k.gp",
"chars": 5225,
"preview": "set term postscript color eps enhanced 22\nset output \"pset-ll-1k.eps\"\n\nset size 0.95,1.12\n\nX=0.1\nW=0.26\nM=0.025\n\nload \"s"
},
{
"path": "graphs/plots/pset-tree-1k.gp",
"chars": 5233,
"preview": "set term postscript color eps enhanced 22\nset output \"pset-tree-1k.eps\"\n\nset size 0.95,1.12\n\nX=0.1\nW=0.26\nM=0.025\n\nload "
},
{
"path": "graphs/plots/pset-tree-1m.gp",
"chars": 5617,
"preview": "set term postscript color eps enhanced 22\nset output \"pset-tree-1m.eps\"\n\nset size 0.95,1.12\n\nX=0.1\nW=0.26\nM=0.025\n\nload "
},
{
"path": "graphs/plots/psps-integer.gp",
"chars": 4762,
"preview": "set term postscript color eps enhanced 22\nset output \"psps-integer.eps\"\n\nset size 0.95,1.12\n\nS1=0.005\nS2=0.3\nX=0.1+S1\nW="
},
{
"path": "graphs/plots/q-array-enq-deq.gp",
"chars": 1183,
"preview": "set term postscript color eps enhanced 22\nset output \"q-array-enq-deq.eps\"\n\n#set size 0.95,0.6\n#X=0.09\n#W=0.26\n#M=0.02\n\n"
},
{
"path": "graphs/plots/q-enq-deq.gp",
"chars": 2896,
"preview": "set term postscript color eps enhanced 22\nset output \"q-enq-deq.eps\"\n\nset size 0.95,0.6\n\nX=0.1\nW=0.375\nM=0.075\n\nload \"st"
},
{
"path": "graphs/plots/q-ll-enq-deq.gp",
"chars": 1276,
"preview": "set term postscript color eps enhanced 22\nset output \"q-ll-enq-deq.eps\"\n\n#set size 0.95,0.6\n#X=0.09\n#W=0.26\n#M=0.02\n\nloa"
},
{
"path": "graphs/plots/set-hash-1k.gp",
"chars": 4693,
"preview": "set term postscript color eps enhanced 22\nset output \"set-hash-1k.eps\"\n\nset size 0.95,1.12\n\nX=0.1\nW=0.26\nM=0.025\n\nload \""
},
{
"path": "graphs/plots/set-ll-10k.gp",
"chars": 5357,
"preview": "set term postscript color eps enhanced 22\nset output \"set-ll-10k.eps\"\n\nset size 0.95,1.08\n\nX=0.09\nW=0.26\nM=0.02\n\nload \"s"
}
]
// ... and 212 more files (download for full content)
About this extraction
This page contains the full source code of the pramalhe/OneFile GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 412 files (3.5 MB), approximately 950.3k tokens, and a symbol index with 3769 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.