1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
// This file is part of intel-tsx-rtm. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/intel-tsx-rtm/master/COPYRIGHT. No part of predicator, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file. // Copyright © 2017 The developers of intel-tsx-rtm. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/intel-tsx-rtm/master/COPYRIGHT. bitflags! { /// This structure wraps the results of an execution of a transaction. pub struct HardwareMemoryTransactionResult: u32 { #[doc(hidden)] const _XABORT_EXPLICIT = (1 << 0); #[doc(hidden)] const _XABORT_RETRY = (1 << 1); #[doc(hidden)] const _XABORT_CONFLICT = (1 << 2); #[doc(hidden)] const _XABORT_CAPACITY = (1 << 3); #[doc(hidden)] const _XABORT_DEBUG = (1 << 4); #[doc(hidden)] const _XABORT_NESTED = (1 << 5); } } impl HardwareMemoryTransactionResult { /// Return this from `TransactionCallback` if a transaction is successful. pub const TransactionIsSuccessful: u8 = 0; /// Return this from `TransactionCallback` if a transaction fails due to a busy lock. /// Unofficial, see source code comments in <https://github.com/gcc-mirror/gcc/blob/da8dff89fa9398f04b107e388cb706517ced9505/libitm/config/x86/target.h>. pub const TransactionFailedDueToBusyLock: u8 = 0xFF; #[inline(always)] fn new(status: u32) -> Self { Self { bits: status, } } // /// The transaction succeeded. // #[inline(always)] // pub fn transaction_was_successful(self) -> bool // { // self.is_empty() // } /// Returns `Some(status_code)` if explicitly aborted. /// `status_code` will never be zero. /// Transaction was explicitly aborted with `_xabort()`. The parameter passed to `_xabort` is available with `_XABORT_CODE(status)`. #[inline(always)] pub fn transaction_was_explicitly_aborted_by_callback(self) -> Option<u8> { if self.contains(Self::_XABORT_EXPLICIT) { // Equivalent to `_XCODE_ABORT(status)`. let status = (self.bits >> 24) & 0xFF; Some(status as u8) } else { None } } /// Transaction can be retried. #[inline(always)] pub fn transaction_retry_is_possible(self) -> bool { self.contains(Self::_XABORT_RETRY) } /// Transaction abort due to a memory conflict with another thread. /// A re-try of this transaction is likely to succeed. /// Ideally use a back off. #[inline(always)] pub fn transaction_was_aborted_due_to_conflict_with_another_thread(self) -> bool { self.contains(Self::_XABORT_CONFLICT) } /// Capacity of the cache was exceeded. /// A re-try of this transaction might succeed, but it's not likely. #[inline(always)] pub fn transaction_was_aborted_due_to_using_too_much_memory(self) -> bool { self.contains(Self::_XABORT_CAPACITY) } /// Transaction aborted due to a debug trap. /// A re-try of this transaction is likely to succeed if the debug trap is removed. #[inline(always)] pub fn transaction_was_aborted_due_to_a_debug_trap(self) -> bool { self.contains(Self::_XABORT_DEBUG) } /// Transaction abort in an inner nested transaction. /// Transactions inside transactions are a failure of logic, and so it is highly unlikely that a retry would succeed. #[inline(always)] pub fn transaction_was_aborted_due_to_issuing_a_nested_transaction(self) -> bool { self.contains(Self::_XABORT_NESTED) } }