diff options
Diffstat (limited to 'storage/maria/trxman.c')
-rw-r--r-- | storage/maria/trxman.c | 258 |
1 files changed, 0 insertions, 258 deletions
diff --git a/storage/maria/trxman.c b/storage/maria/trxman.c deleted file mode 100644 index a3e746af9ca..00000000000 --- a/storage/maria/trxman.c +++ /dev/null @@ -1,258 +0,0 @@ - -#include <my_global.h> -#include <my_sys.h> -#include <lf.h> -#include "trxman.h" - -TRX active_list_min, active_list_max, - committed_list_min, committed_list_max, *pool; - -pthread_mutex_t LOCK_trx_list; -uint trxman_active_transactions, trxman_allocated_transactions; -TrID global_trid_generator; - -TRX **short_id_to_trx; -my_atomic_rwlock_t LOCK_short_id_to_trx; - -LF_HASH trid_to_trx; - -static byte *trx_get_hash_key(const byte *trx,uint* len, my_bool unused) -{ - *len= sizeof(TrID); - return (byte *) & ((*((TRX **)trx))->trid); -} - -int trxman_init() -{ - pthread_mutex_init(&LOCK_trx_list, MY_MUTEX_INIT_FAST); - active_list_max.trid= active_list_min.trid= 0; - active_list_max.min_read_from=~0; - active_list_max.next= active_list_min.prev= 0; - active_list_max.prev= &active_list_min; - active_list_min.next= &active_list_max; - trxman_active_transactions= 0; - trxman_allocated_transactions= 0; - - committed_list_max.commit_trid= ~0; - committed_list_max.next= committed_list_min.prev= 0; - committed_list_max.prev= &committed_list_min; - committed_list_min.next= &committed_list_max; - - pool=0; - global_trid_generator=0; /* set later by recovery code */ - lf_hash_init(&trid_to_trx, sizeof(TRX*), LF_HASH_UNIQUE, - 0, 0, trx_get_hash_key, 0); - my_atomic_rwlock_init(&LOCK_short_id_to_trx); - short_id_to_trx=(TRX **)my_malloc(SHORT_ID_MAX*sizeof(TRX*), - MYF(MY_WME|MY_ZEROFILL)); - if (!short_id_to_trx) - return 1; - short_id_to_trx--; /* min short_id is 1 */ - - return 0; -} - -int trxman_destroy() -{ - DBUG_ASSERT(trid_to_trx.count == 0); - DBUG_ASSERT(trxman_active_transactions == 0); - DBUG_ASSERT(active_list_max.prev == &active_list_min); - DBUG_ASSERT(active_list_min.next == &active_list_max); - DBUG_ASSERT(committed_list_max.prev == &committed_list_min); - DBUG_ASSERT(committed_list_min.next == &committed_list_max); - while (pool) - { - TRX *tmp=pool->next; - my_free((void *)pool, MYF(0)); - pool=tmp; - } - lf_hash_destroy(&trid_to_trx); - pthread_mutex_destroy(&LOCK_trx_list); - my_atomic_rwlock_destroy(&LOCK_short_id_to_trx); - my_free((void *)(short_id_to_trx+1), MYF(0)); -} - -static TrID new_trid() -{ - DBUG_ASSERT(global_trid_generator < 0xffffffffffffLL); - safe_mutex_assert_owner(&LOCK_trx_list); - return ++global_trid_generator; -} - -static void set_short_id(TRX *trx) -{ - int i= (global_trid_generator + (intptr)trx) * 312089 % SHORT_ID_MAX; - my_atomic_rwlock_wrlock(&LOCK_short_id_to_trx); - for ( ; ; i= i % SHORT_ID_MAX + 1) /* the range is [1..SHORT_ID_MAX] */ - { - void *tmp=NULL; - if (short_id_to_trx[i] == NULL && - my_atomic_casptr((void **)&short_id_to_trx[i], &tmp, trx)) - break; - } - my_atomic_rwlock_wrunlock(&LOCK_short_id_to_trx); - trx->short_id= i; -} - -TRX *trxman_new_trx() -{ - TRX *trx; - - my_atomic_add32(&trxman_active_transactions, 1); - - /* - see trxman_end_trx to see why we need a mutex here - - and as we have a mutex, we can as well do everything - under it - allocating a TRX, incrementing trxman_active_transactions, - setting trx->min_read_from. - - Note that all the above is fast. generating short_id may be slow, - as it involves scanning a big array - so it's still done - outside of the mutex. - */ - - pthread_mutex_lock(&LOCK_trx_list); - trx=pool; - while (trx && !my_atomic_casptr((void **)&pool, (void **)&trx, trx->next)) - /* no-op */; - - if (!trx) - { - trx=(TRX *)my_malloc(sizeof(TRX), MYF(MY_WME)); - trxman_allocated_transactions++; - } - if (!trx) - return 0; - - trx->min_read_from= active_list_min.next->trid; - - trx->trid= new_trid(); - trx->short_id= 0; - - trx->next= &active_list_max; - trx->prev= active_list_max.prev; - active_list_max.prev= trx->prev->next= trx; - pthread_mutex_unlock(&LOCK_trx_list); - - trx->pins=lf_hash_get_pins(&trid_to_trx); - - if (!trx->min_read_from) - trx->min_read_from= trx->trid; - - trx->commit_trid=0; - - set_short_id(trx); /* this must be the last! */ - - - return trx; -} - -/* - remove a trx from the active list, - move to committed list, - set commit_trid - - TODO - integrate with lock manager, log manager. That means: - a common "commit" mutex - forcing the log and setting commit_trid - must be done atomically (QQ how the heck it could be done with - group commit ???) - - trid_to_trx, active_list_*, and committed_list_* can be - updated asyncronously. -*/ -void trxman_end_trx(TRX *trx, my_bool commit) -{ - int res; - TRX *free_me= 0; - LF_PINS *pins= trx->pins; - - pthread_mutex_lock(&LOCK_trx_list); - trx->next->prev= trx->prev; - trx->prev->next= trx->next; - - if (trx->prev == &active_list_min) - { - TRX *t; - for (t= committed_list_min.next; - t->commit_trid < active_list_min.next->min_read_from; - t= t->next) /* no-op */; - - if (t != committed_list_min.next) - { - free_me= committed_list_min.next; - committed_list_min.next= t; - t->prev->next=0; - t->prev= &committed_list_min; - } - } - - my_atomic_rwlock_wrlock(&LOCK_short_id_to_trx); - my_atomic_storeptr((void **)&short_id_to_trx[trx->short_id], 0); - my_atomic_rwlock_wrunlock(&LOCK_short_id_to_trx); - - if (commit && active_list_min.next != &active_list_max) - { - trx->commit_trid= global_trid_generator; - - trx->next= &committed_list_max; - trx->prev= committed_list_max.prev; - committed_list_max.prev= trx->prev->next= trx; - - res= lf_hash_insert(&trid_to_trx, pins, &trx); - DBUG_ASSERT(res == 0); - } - else - { - trx->next=free_me; - free_me=trx; - } - pthread_mutex_unlock(&LOCK_trx_list); - - my_atomic_add32(&trxman_active_transactions, -1); - - while (free_me) - { - int res; - TRX *t= free_me; - free_me= free_me->next; - - res= lf_hash_delete(&trid_to_trx, pins, &t->trid, sizeof(TrID)); - - trxman_free_trx(t); - } - - lf_hash_put_pins(pins); -} - -/* free a trx (add to the pool, that is */ -void trxman_free_trx(TRX *trx) -{ - TRX *tmp=pool; - - do - { - trx->next=tmp; - } while (!my_atomic_casptr((void **)&pool, (void **)&tmp, trx)); -} - -my_bool trx_can_read_from(TRX *trx, TrID trid) -{ - TRX *found; - my_bool can; - - if (trid < trx->min_read_from) - return TRUE; - if (trid > trx->trid) - return FALSE; - - found= lf_hash_search(&trid_to_trx, trx->pins, &trid, sizeof(trid)); - if (!found) - return FALSE; /* not in the hash = cannot read */ - - can= found->commit_trid < trx->trid; - lf_unpin(trx->pins, 2); - return can; -} - |