34 #if !defined(SERVER_MODE) 35 #define pthread_mutex_init(a, b) 36 #define pthread_mutex_destroy(a) 37 #define pthread_mutex_lock(a) 0 38 #define pthread_mutex_trylock(a) 0 39 #define pthread_mutex_unlock(a) 63 #define OF_GET_REF(p,o) (void * volatile *) (((char *)(p)) + (o)) 64 #define OF_GET_PTR(p,o) (void *) (((char *)(p)) + (o)) 65 #define OF_GET_PTR_DEREF(p,o) (*OF_GET_REF (p,o)) 70 #define ADDR_HAS_MARK(p) (((long long volatile) (p)) & 0x1) 71 #define ADDR_WITH_MARK(p) ((void * volatile) (((long long volatile) (p)) | 0x1)) 72 #define ADDR_STRIP_MARK(p) ((void * volatile) (((long long volatile) (p)) & (~((long long) 0x1)))) 75 #if defined (__GNUC__) 76 #pragma GCC diagnostic ignored "-Wignored-qualifiers" 79 #pragma warning (disable : 4197) 112 #if defined (UNITTEST_LF) 113 #define LF_UNITTEST_INC(lf_stat, incval) ATOMIC_INC_64 (lf_stat, incval) 115 #define LF_UNITTEST_INC(lf_stat, incval) 118 #if defined (UNITTEST_LF) || defined (UNITTEST_CQ) 121 #define assert(cond) if (!(cond)) abort () 122 #define assert_release(cond) if (!(cond)) abort () 144 return ((lvpid->
pageid | ((
unsigned int) lvpid->
volid) << 24) % htsize);
171 ((
VPID *) dest)->pageid = ((
VPID *) src)->pageid;
172 ((
VPID *) dest)->volid = ((
VPID *) src)->volid;
217 #if defined (UNITTEST_LF) 219 sys->
entries[
i].locked_mutex_line = -1;
289 entry = &sys->
entries[entry_idx];
293 #if defined (UNITTEST_LF) 294 entry->locked_mutex =
NULL;
295 entry->locked_mutex_line = -1;
381 int pos = i * LF_BITFIELD_WORD_SIZE + j;
384 if (minvalue > fetch)
552 rtop = *((
void *
volatile *) top);
555 while (!ATOMIC_CAS_ADDR (top, rtop, entry));
590 if (ATOMIC_CAS_ADDR (top, rtop, prev))
624 if (new_entry ==
NULL)
648 while (!ATOMIC_CAS_ADDR (&freelist->
available, top, tail));
673 assert (initial_blocks >= 1);
694 for (i = 0; i < initial_blocks; i++)
738 while (entry !=
NULL);
755 bool local_tran =
false;
869 bool local_tran =
false;
934 UINT64 min_tran_id = 0;
935 int transported_count = 0;
936 void *list =
NULL, *list_trailer =
NULL;
937 void *aval_first =
NULL, *aval_last =
NULL;
949 if (min_tran_id <= tran_entry->last_cleanup_id)
959 if (aval_first ==
NULL)
964 if (*del_id < min_tran_id)
977 transported_count = 1;
1000 if (aval_first !=
NULL)
1002 if (list_trailer !=
NULL)
1022 while (!ATOMIC_CAS_ADDR (&freelist->
available, old_head, aval_first));
1025 ATOMIC_INC_32 (&freelist->
available_cnt, transported_count);
1026 ATOMIC_INC_32 (&freelist->
retired_cnt, -transported_count);
1049 pthread_mutex_t *entry_mutex;
1061 curr = *((
void *
volatile *) curr_p);
1064 while (curr !=
NULL)
1082 curr = *((
void *
volatile *) curr_p);
1103 pthread_mutex_t *entry_mutex;
1120 curr = *((
void *
volatile *) curr_p);
1123 while (curr_p !=
NULL)
1144 curr = *((
void *
volatile *) curr_p);
1149 (*entry) = new_entry;
1158 if (!ATOMIC_CAS_ADDR (curr_p, (
void *)
NULL, (*entry)))
1167 goto restart_search;
1194 pthread_mutex_t *entry_mutex;
1213 while (curr !=
NULL)
1239 goto restart_search;
1295 #define LF_ASSERT_USE_MUTEX_OR_TRAN_STARTED() \ 1296 assert (is_tran_started == !edesc->using_mutex); \ 1297 assert (!edesc->using_mutex || entry_mutex) 1300 #define LF_START_TRAN() \ 1301 if (!is_tran_started) lf_tran_start_with_mb (tran, false); is_tran_started = true 1302 #define LF_START_TRAN_FORCE() \ 1303 assert (!is_tran_started); lf_tran_start_with_mb (tran, false); is_tran_started = true 1306 #define LF_END_TRAN() \ 1307 if (is_tran_started) lf_tran_end_with_mb (tran) 1309 #define LF_END_TRAN_FORCE() \ 1310 assert (is_tran_started); lf_tran_end_with_mb (tran); is_tran_started = false 1312 #if defined (UNITTEST_LF) 1314 #define LF_LOCK_ENTRY(tolock) \ 1315 assert (tran->locked_mutex == NULL); \ 1316 assert (edesc->using_mutex); \ 1317 assert ((tolock) != NULL); \ 1318 assert (entry_mutex == NULL); \ 1320 entry_mutex = (pthread_mutex_t *) OF_GET_PTR (tolock, edesc->of_mutex); \ 1321 tran->locked_mutex_line = __LINE__; \ 1322 tran->locked_mutex = entry_mutex; \ 1323 rv = pthread_mutex_lock (entry_mutex) 1326 #define LF_UNLOCK_ENTRY() \ 1327 if (edesc->using_mutex && entry_mutex) \ 1329 assert (tran->locked_mutex == entry_mutex); \ 1330 tran->locked_mutex = NULL; \ 1331 pthread_mutex_unlock (entry_mutex); \ 1332 entry_mutex = NULL; \ 1335 #define LF_UNLOCK_ENTRY_FORCE() \ 1336 assert (edesc->using_mutex && entry_mutex != NULL); \ 1337 assert (tran->locked_mutex == entry_mutex); \ 1338 tran->locked_mutex = NULL; \ 1339 pthread_mutex_unlock (entry_mutex); \ 1343 #define LF_LOCK_ENTRY(tolock) \ 1344 assert (edesc->using_mutex); \ 1345 assert ((tolock) != NULL); \ 1346 assert (entry_mutex == NULL); \ 1348 entry_mutex = (pthread_mutex_t *) OF_GET_PTR (tolock, edesc->of_mutex); \ 1349 rv = pthread_mutex_lock (entry_mutex) 1352 #define LF_UNLOCK_ENTRY() \ 1353 if (edesc->using_mutex && entry_mutex) \ 1355 pthread_mutex_unlock (entry_mutex); \ 1356 entry_mutex = NULL; \ 1359 #define LF_UNLOCK_ENTRY_FORCE() \ 1360 assert (edesc->using_mutex && entry_mutex != NULL); \ 1361 pthread_mutex_unlock (entry_mutex); \ 1365 pthread_mutex_t *entry_mutex =
NULL;
1369 bool is_tran_started =
false;
1379 if (inserted !=
NULL)
1394 while (curr_p !=
NULL)
1396 assert (is_tran_started);
1440 goto restart_search;
1556 if (!ATOMIC_CAS_ADDR (curr_p, (
void *)
NULL, (*entry)))
1585 goto restart_search;
1611 #undef LF_ASSERT_USE_MUTEX_OR_TRAN_STARTED 1612 #undef LF_START_TRAN 1613 #undef LF_START_TRAN_FORCE 1615 #undef LF_END_TRAN_FORCE 1616 #undef LF_LOCK_ENTRY 1617 #undef LF_UNLOCK_ENTRY 1618 #undef LF_UNLOCK_ENTRY_FORCE 1638 #define LF_START_TRAN_FORCE() \ 1639 assert (!is_tran_started); lf_tran_start_with_mb (tran, false); is_tran_started = true 1642 #define LF_PROMOTE_TRAN_FORCE() \ 1643 assert (is_tran_started); MEMORY_BARRIER (); lf_tran_start_with_mb (tran, true) 1647 #define LF_END_TRAN_FORCE() \ 1648 assert (is_tran_started); lf_tran_end_with_mb (tran); is_tran_started = false 1650 #if defined (UNITTEST_LF) 1652 #define LF_LOCK_ENTRY(tolock) \ 1653 assert (edesc->using_mutex); \ 1654 assert ((tolock) != NULL); \ 1655 assert (entry_mutex == NULL); \ 1657 entry_mutex = (pthread_mutex_t *) OF_GET_PTR (tolock, edesc->of_mutex); \ 1658 assert (tran->locked_mutex == NULL); \ 1659 tran->locked_mutex = entry_mutex; \ 1660 tran->locked_mutex_line = __LINE__; \ 1661 rv = pthread_mutex_lock (entry_mutex) 1664 #define LF_UNLOCK_ENTRY_FORCE() \ 1665 assert (edesc->using_mutex && entry_mutex != NULL); \ 1666 assert (tran->locked_mutex == entry_mutex); \ 1667 tran->locked_mutex = NULL; \ 1668 pthread_mutex_unlock (entry_mutex); \ 1672 #define LF_LOCK_ENTRY(tolock) \ 1673 assert (edesc->using_mutex); \ 1674 assert ((tolock) != NULL); \ 1675 assert (entry_mutex == NULL); \ 1677 entry_mutex = (pthread_mutex_t *) OF_GET_PTR (tolock, edesc->of_mutex); \ 1678 rv = pthread_mutex_lock (entry_mutex) 1681 #define LF_UNLOCK_ENTRY_FORCE() \ 1682 assert (edesc->using_mutex && entry_mutex != NULL); \ 1683 pthread_mutex_unlock (entry_mutex); \ 1687 pthread_mutex_t *entry_mutex =
NULL;
1688 void **curr_p, **next_p;
1691 bool is_tran_started =
false;
1694 if (success !=
NULL)
1714 while (curr !=
NULL)
1719 if (locked_entry !=
NULL && locked_entry != curr)
1753 goto restart_search;
1767 #if defined (UNITTEST_LF) 1768 assert (locked_entry !=
NULL && locked_entry == curr);
1772 #if defined (UNITTEST_LF) 1773 assert (tran->locked_mutex !=
NULL && tran->locked_mutex == entry_mutex);
1781 if (!ATOMIC_CAS_ADDR (curr_p, curr, next))
1809 goto restart_search;
1836 if (success !=
NULL)
1857 #undef LF_START_TRAN_FORCE 1858 #undef LF_PROMOTE_TRAN_FORCE 1859 #undef LF_END_TRAN_FORCE 1860 #undef LF_LOCK_ENTRY 1861 #undef LF_UNLOCK_ENTRY_FORCE 1890 table->
buckets = (
void **) malloc (
sizeof (
void *) * hash_size);
1899 memset (table->
buckets, 0, sizeof (
void *) * hash_size);
1903 table->
backbuffer = (
void **) malloc (
sizeof (
void *) * hash_size);
1915 for (i = 0; i < (int) hash_size; i++)
1950 while (entry !=
NULL)
1990 unsigned int hash_value;
2051 unsigned int hash_value;
2080 bflags &= ~LF_LIST_BR_RESTARTED;
2202 unsigned int hash_value;
2212 if (success !=
NULL)
2227 bflags &= ~LF_LIST_BR_RESTARTED;
2249 void **old_buckets, *curr, **next_p, *next;
2250 void *ret_head =
NULL, *ret_tail =
NULL;
2251 pthread_mutex_t *mutex_p;
2252 int rv,
i, ret_count = 0;
2258 #if defined (UNITTEST_LF) 2273 for (i = 0; i < (int) table->
hash_size; i++)
2284 for (i = 0; i < (int) table->
hash_size; i++)
2316 if (ret_head ==
NULL)
2334 if (ret_head !=
NULL)
2412 pthread_mutex_t *mx;
2419 it->
curr = *(
void *
volatile *) next_p;
2450 pthread_mutex_t *mx;
2470 #if defined (UNITTEST_LF) 2478 lf_reset_counters (
void)
int lf_freelist_transport(LF_TRAN_ENTRY *tran_entry, LF_FREELIST *freelist)
#define LF_LIST_BF_INSERT_GIVEN
int mati_refresh_interval
#define LF_END_TRAN_FORCE()
#define LF_NULL_TRANSACTION_ID
int lf_list_delete(LF_TRAN_ENTRY *tran, void **list_p, void *key, void *locked_entry, int *behavior_flags, LF_ENTRY_DESCRIPTOR *edesc, LF_FREELIST *freelist, int *success)
#define ADDR_STRIP_MARK(p)
static INT64 lf_list_inserts
static INT64 lf_list_inserts_claim
unsigned int of_local_next
void lf_hash_destroy(LF_HASH_TABLE *table)
LF_HASH_TABLE * hash_table
LF_ENTRY_INITIALIZE_FUNC f_init
LF_TRAN_ENTRY * lf_tran_request_entry(LF_TRAN_SYSTEM *sys)
static const LF_BITMAP_STYLE LF_BITMAP_ONE_CHUNK
void * lf_hash_iterate(LF_HASH_TABLE_ITERATOR *it)
UINT64 global_transaction_id
pthread_mutex_t backbuffer_mutex
LF_TRAN_SYSTEM sessions_Ts
LF_ENTRY_UNINITIALIZE_FUNC f_uninit
int lf_hash_delete_already_locked(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, void *locked_entry, int *success)
int lf_hash_find(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, void **entry)
void free_entry(int entry_idx)
static INT64 lf_list_inserts_fail_link
void lf_hash_create_iterator(LF_HASH_TABLE_ITERATOR *iterator, LF_TRAN_ENTRY *tran_entry, LF_HASH_TABLE *table)
static INT64 lf_list_deletes
LF_ENTRY_FREE_FUNC f_free
static INT64 lf_list_deletes_fail_mark_next
int lf_initialize_transaction_systems(int max_threads)
static INT64 lf_list_inserts_found
void lf_tran_system_destroy(LF_TRAN_SYSTEM *sys)
void * lf_stack_pop(void **top, LF_ENTRY_DESCRIPTOR *edesc)
#define lf_tran_end_with_mb(entry)
LF_TRAN_SYSTEM spage_saving_Ts
void * lf_freelist_claim(LF_TRAN_ENTRY *tran_entry, LF_FREELIST *freelist)
void lf_tran_destroy_entry(LF_TRAN_ENTRY *entry)
LF_ENTRY_DESCRIPTOR * entry_desc
#define LF_BITMAP_COUNT_ALIGN(count)
LF_ENTRY_DESCRIPTOR * entry_desc
void lf_destroy_transaction_systems(void)
#define ADDR_WITH_MARK(p)
void lf_tran_end(LF_TRAN_ENTRY *entry)
#define lf_tran_start_with_mb(entry, incr)
unsigned int of_del_tran_id
static bool tran_systems_initialized
int lf_tran_system_init(LF_TRAN_SYSTEM *sys, int max_threads)
int lf_hash_init(LF_HASH_TABLE *table, LF_FREELIST *freelist, unsigned int hash_size, LF_ENTRY_DESCRIPTOR *edesc)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
LF_TRAN_SYSTEM obj_lock_ent_Ts
#define LF_PROMOTE_TRAN_FORCE()
int lf_callback_vpid_compare(void *vpid_1, void *vpid_2)
UINT64 min_active_transaction_id
static INT64 lf_list_deletes_found
LF_ENTRY_KEY_COPY_FUNC f_key_copy
void lf_tran_return_entry(LF_TRAN_ENTRY *entry)
LF_TRAN_SYSTEM * tran_system
LF_ENTRY_KEY_COMPARE_FUNC f_key_cmp
static INT64 lf_deletes_restart
#define ER_OUT_OF_VIRTUAL_MEMORY
#define pthread_mutex_lock(a)
#define LF_LIST_BF_IS_FLAG_SET(bf, flag)
static INT64 lf_list_deletes_not_found
static INT64 lf_list_deletes_success_unlink
#define LF_ASSERT_USE_MUTEX_OR_TRAN_STARTED()
int lf_stack_push(void **top, void *entry, LF_ENTRY_DESCRIPTOR *edesc)
LF_TRAN_SYSTEM dwb_slots_Ts
int lf_freelist_retire(LF_TRAN_ENTRY *tran_entry, LF_FREELIST *freelist, void *entry)
void lf_tran_compute_minimum_transaction_id(LF_TRAN_SYSTEM *sys)
#define pthread_mutex_unlock(a)
unsigned int lf_callback_vpid_hash(void *vpid, int htsize)
#define LF_UNITTEST_INC(lf_stat, incval)
#define LF_START_TRAN_FORCE()
#define LF_LIST_BF_RESTART_ON_DUPLICATE
static INT64 lf_list_inserts_save_temp_1
static INT64 lf_transports
int lf_io_list_find(void **list_p, void *key, LF_ENTRY_DESCRIPTOR *edesc, void **entry)
LF_TRAN_SYSTEM global_unique_stats_Ts
int lf_hash_find_or_insert(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, void **entry, int *inserted)
static INT64 lf_list_deletes_fail_unlink
#define LF_LOCK_ENTRY(tolock)
LF_TRAN_SYSTEM hfid_table_Ts
static int lf_list_insert_internal(LF_TRAN_ENTRY *tran, void **list_p, void *key, int *behavior_flags, LF_ENTRY_DESCRIPTOR *edesc, LF_FREELIST *freelist, void **entry, int *inserted)
static INT64 lf_list_deletes_not_match
LF_ENTRY_DUPLICATE_KEY_HANDLER f_duplicate
int lf_freelist_init(LF_FREELIST *freelist, int initial_blocks, int block_size, LF_ENTRY_DESCRIPTOR *edesc, LF_TRAN_SYSTEM *tran_system)
LF_TRAN_SYSTEM catalog_Ts
#define LF_BITFIELD_WORD_SIZE
#define LF_LIST_BF_FIND_OR_INSERT
#define LF_LIST_BF_RETURN_ON_RESTART
#define LF_LIST_BR_SET_FLAG(br, flag)
static void error(const char *msg)
LF_ENTRY_HASH_FUNC f_hash
#define LF_LIST_BF_LOCK_ON_DELETE
std::atomic< unsigned int > * bitfield
static INT64 lf_hash_size
static INT64 lf_inserts_restart
LF_ENTRY_ALLOC_FUNC f_alloc
void lf_hash_clear(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table)
int lf_io_list_find_or_insert(void **list_p, void *new_entry, LF_ENTRY_DESCRIPTOR *edesc, void **entry)
int lf_hash_insert(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, void **entry, int *inserted)
#define pthread_mutex_init(a, b)
static INT64 lf_claims_temp
int lf_list_find(LF_TRAN_ENTRY *tran, void **list_p, void *key, int *behavior_flags, LF_ENTRY_DESCRIPTOR *edesc, void **entry)
LF_ENTRY_DESCRIPTOR * entry_desc
#define LF_TRAN_SYSTEM_INITIALIZER
#define free_and_init(ptr)
#define LF_UNLOCK_ENTRY_FORCE()
static INT64 lf_list_inserts_save_temp_2
void lf_tran_start(LF_TRAN_ENTRY *entry, bool incr)
void lf_freelist_destroy(LF_FREELIST *freelist)
int lf_hash_insert_given(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, void **entry, int *inserted)
LF_TRAN_ENTRY * tran_entry
#define pthread_mutex_destroy(a)
static int lf_hash_delete_internal(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, void *locked_entry, int bflags, int *success)
int lf_hash_delete(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, int *success)
#define LF_UNLOCK_ENTRY()
LF_TRAN_SYSTEM * tran_system
#define VOLATILE_ACCESS(v, t)
#define LF_LIST_BR_RESTARTED
static INT64 lf_list_inserts_success_link
#define OF_GET_PTR_DEREF(p, o)
#define LF_TRAN_CLEANUP_NECESSARY(e)
void init(chunking_style style, int entries_count, float usage_ratio)
LF_TRAN_SYSTEM free_sort_list_Ts
int lf_callback_vpid_copy(void *src, void *dest)
LF_TRAN_SYSTEM fpcache_Ts
#define LF_BITMAP_FULL_USAGE_RATIO
static int lf_freelist_alloc_block(LF_FREELIST *freelist)
static int lf_hash_insert_internal(LF_TRAN_ENTRY *tran, LF_HASH_TABLE *table, void *key, int bflags, void **entry, int *inserted)
LF_TRAN_SYSTEM obj_lock_res_Ts