00001
00092 #include <sys/types.h>
00093 #include <sys/stat.h>
00094 #include <pthread.h>
00095 #include <unistd.h>
00096 #include <stddef.h>
00097 #include <misc/result.h>
00098 #include <misc/pool.h>
00099 #include <misc/malloc.h>
00100 #include <misc/debug.h>
00101 #include <misc/mutex.h>
00102 #include <core/config.h>
00103 #include <core/sentinel.h>
00104 #include <core/tx.h>
00105 #include <core/txdesc.h>
00106
00107 #define TXC_SENTINEL_NOOWNER 0x0
00108
00110 struct txc_sentinel_s {
00111 txc_mutex_t sentinel_mutex;
00112 txc_mutex_t synch_mutex;
00113 int id;
00114 int refcnt;
00115 txc_tx_t *owner;
00116 txc_sentinelmgr_t *manager;
00117 };
00118
00120 struct txc_sentinel_list_entry_s {
00121 txc_sentinel_t *sentinel;
00122 txc_result_t status;
00123 };
00124
00126 struct txc_sentinel_list_s {
00127 txc_sentinel_list_entry_t *entries;
00128 unsigned int num_entries;
00129 unsigned int size;
00130 txc_sentinelmgr_t *manager;
00131 };
00132
00133
00135 struct txc_sentinelmgr_s {
00136 txc_mutex_t mutex;
00137 txc_pool_t *pool_sentinel;
00138 };
00139
00140
00141 static inline void sentinel_list_print(txc_sentinel_list_t *sentinel_list, char *heading);
00142 static inline txc_result_t enlist_sentinel(txc_sentinel_list_t *sentinel_list, txc_sentinel_t *sentinel, txc_result_t status);
00143 static inline void backoff(txc_tx_t *txd);
00144
00145
00146 txc_sentinelmgr_t *txc_g_sentinelmgr;
00147
00148
00157 txc_result_t
00158 txc_sentinelmgr_create(txc_sentinelmgr_t **sentinelmgrp)
00159 {
00160 txc_result_t result;
00161 txc_pool_object_t *pool_object;
00162 txc_sentinel_t *sentinel;
00163 int i;
00164
00165 *sentinelmgrp = (txc_sentinelmgr_t *) MALLOC(sizeof(txc_sentinelmgr_t));
00166 if (*sentinelmgrp == NULL) {
00167 return TXC_R_NOMEMORY;
00168 }
00169
00170 if ((result = txc_pool_create(&((*sentinelmgrp)->pool_sentinel),
00171 sizeof(txc_sentinel_t),
00172 TXC_SENTINEL_NUM,
00173 NULL)) != TXC_R_SUCCESS)
00174 {
00175 FREE(*sentinelmgrp);
00176 return result;
00177 }
00178 TXC_MUTEX_INIT(&((*sentinelmgrp)->mutex), NULL);
00179 for (i = 0,
00180 pool_object = txc_pool_object_first((*sentinelmgrp)->pool_sentinel,
00181 TXC_POOL_OBJECT_ALLOCATED &
00182 TXC_POOL_OBJECT_FREE);
00183 pool_object != NULL;
00184 i++, pool_object = txc_pool_object_next(pool_object))
00185 {
00186 sentinel = (txc_sentinel_t *) txc_pool_object_of(pool_object);
00187 TXC_MUTEX_INIT(&sentinel->synch_mutex, NULL);
00188 TXC_MUTEX_INIT(&sentinel->sentinel_mutex, NULL);
00189 sentinel->id = i;
00190 sentinel->manager = *sentinelmgrp;
00191 sentinel->owner = TXC_SENTINEL_NOOWNER;
00192 }
00193
00194 return TXC_R_SUCCESS;
00195 }
00196
00197
00205 void
00206 txc_sentinelmgr_destroy(txc_sentinelmgr_t **sentinelmgrp)
00207 {
00208 txc_pool_destroy(&((*sentinelmgrp)->pool_sentinel));
00209 FREE(*sentinelmgrp);
00210 *sentinelmgrp = NULL;
00211 }
00212
00213
00214 txc_result_t
00215 txc_sentinel_create(txc_sentinelmgr_t *sentinelmgr, txc_sentinel_t **sentinelp)
00216 {
00217 txc_result_t result;
00218 txc_sentinel_t *sentinel;
00219
00220 if ((result = txc_pool_object_alloc(sentinelmgr->pool_sentinel,
00221 (void **) &sentinel, 1))
00222 != TXC_R_SUCCESS)
00223 {
00224 TXC_INTERNALERROR("Could not create sentinel object\n");
00225 return result;
00226 }
00227
00228 sentinel->owner = TXC_SENTINEL_NOOWNER;
00229 sentinel->refcnt = 1;
00230 *sentinelp = sentinel;
00231
00232 return TXC_R_SUCCESS;
00233 }
00234
00235
00236 static inline
00237 void
00238 sentinel_destroy(txc_sentinel_t *sentinel)
00239 {
00240 txc_sentinel_t **sentinelp = &sentinel;
00241
00242 txc_pool_object_free(sentinel->manager->pool_sentinel,
00243 (void **) sentinelp, 1);
00244 }
00245
00251 void
00252 txc_sentinel_destroy(txc_sentinel_t *sentinel)
00253 {
00254 TXC_ASSERT(sentinel != NULL);
00255 TXC_MUTEX_LOCK(&sentinel->synch_mutex);
00256 sentinel_destroy(sentinel);
00257 TXC_MUTEX_UNLOCK(&sentinel->synch_mutex);
00258 }
00259
00260
00261 static
00262 void
00263 sentinel_attach(txc_sentinel_t *sentinel)
00264 {
00265 sentinel->refcnt++;
00266 }
00267
00268
00269
00270
00271
00272 static
00273 txc_result_t
00274 sentinel_detach(txc_sentinel_t *sentinel)
00275 {
00276 if (--sentinel->refcnt==0) {
00277 sentinel_destroy(sentinel);
00278 }
00279 return TXC_R_SUCCESS;
00280 }
00281
00282
00293 txc_result_t
00294 txc_sentinel_detach(txc_sentinel_t *sentinel)
00295 {
00296 txc_result_t ret;
00297
00298 TXC_MUTEX_LOCK(&sentinel->synch_mutex);
00299 ret = sentinel_detach(sentinel);
00300 TXC_MUTEX_UNLOCK(&sentinel->synch_mutex);
00301 return ret;
00302 }
00303
00304
00315 static inline
00316 void
00317 sentinel_list_acquire(txc_tx_t *txd, txc_sentinel_list_t *list_acquire)
00318 {
00319 txc_sentinel_list_entry_t *entry;
00320 int i;
00321
00322 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "SENTINEL LIST: ACQUIRE SENTINELS\n");
00323 sentinel_list_print(list_acquire, "SENTINEL_LIST_ACQUIRE");
00324 for (i=0; i<list_acquire->num_entries; i++) {
00325 entry = &list_acquire->entries[i];
00326 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00327 "ACQUIRE SENTINEL %3d: MAY BLOCK\n",
00328 entry->sentinel->id);
00329 TXC_MUTEX_LOCK(&(entry->sentinel->sentinel_mutex));
00330 entry->sentinel->owner = txd;
00331 enlist_sentinel(txd->sentinel_list, entry->sentinel,
00332 TXC_SENTINEL_ACQUIRED |
00333 TXC_SENTINEL_ACQUIREONRETRY);
00334
00335 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00336 "ACQUIRE SENTINEL %3d: SUCCESS\n",
00337 entry->sentinel->id);
00338 }
00339 }
00340
00341
00351 static
00352 void
00353 sentinel_list_release(txc_sentinel_list_t *sentinel_list, int transaction_completion)
00354 {
00355 txc_sentinel_list_entry_t *entry;
00356 int i;
00357
00358 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "SENTINEL LIST: RELEASE SENTINELS\n");
00359 for (i=0; i<sentinel_list->num_entries; i++) {
00360 entry = &sentinel_list->entries[i];
00361 TXC_MUTEX_LOCK(&(entry->sentinel->synch_mutex));
00362 if (entry->status & TXC_SENTINEL_ACQUIRED) {
00363 entry->sentinel->owner = TXC_SENTINEL_NOOWNER;
00364 TXC_MUTEX_UNLOCK(&(entry->sentinel->sentinel_mutex));
00365 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00366 "RELEASE SENTINEL %3d: SUCCESS\n",
00367 entry->sentinel->id);
00368 }
00374 if (transaction_completion) {
00375
00376
00377
00378
00379 sentinel_detach(entry->sentinel);
00380 } else {
00381 if (!(entry->status & TXC_SENTINEL_ACQUIREONRETRY)) {
00382 sentinel_detach(entry->sentinel);
00383 }
00384 }
00385 TXC_MUTEX_UNLOCK(&(entry->sentinel->synch_mutex));
00386 }
00387 }
00388
00389
00390 static
00391 void
00392 sentinel_list_sort(txc_sentinel_list_t *sentinel_list)
00393 {
00394 int i;
00395 int n = sentinel_list->num_entries;
00396 txc_sentinel_list_entry_t entry_temp;
00397 unsigned int swapped;
00398
00399 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "SENTINEL LIST: SORT\n");
00400 do {
00401 swapped = 0;
00402 for (i = 0; i<n-1; i++) {
00403 if (sentinel_list->entries[i].sentinel->id >
00404 sentinel_list->entries[i+1].sentinel->id)
00405 {
00406 entry_temp = sentinel_list->entries[i+1];
00407 sentinel_list->entries[i+1] = sentinel_list->entries[i];
00408 sentinel_list->entries[i] = entry_temp;
00409 swapped = 1;
00410 }
00411 }
00412 n = n-1;
00413 } while (swapped);
00414 }
00415
00416
00417
00418 static inline
00419 void
00420 sentinelmgr_transaction_on_complete(txc_tx_t *txd)
00421 {
00422 #ifdef _TXC_DEBUG_BUILD
00423 sentinel_list_print(txd->sentinel_list, "TRANSACTION ON COMPLETE");
00424 sentinel_list_print(txd->sentinel_list, "SENTINEL LIST (MAIN LIST)");
00425 #endif
00426 sentinel_list_release(txd->sentinel_list, 1);
00427 txc_sentinel_list_init(txd->sentinel_list);
00428 txd->sentinelmgr_undo_action_registered = 0;
00429 txd->sentinelmgr_commit_action_registered = 0;
00430 }
00431
00432
00433 static
00434 void
00435 sentinelmgr_transaction_before_retry(txc_tx_t *txd)
00436 {
00437 int i;
00438 txc_sentinel_list_entry_t *entry;
00439
00440 #ifdef _TXC_DEBUG_BUILD
00441 sentinel_list_print(txd->sentinel_list, "TRANSACTION BEFORE RETRY");
00442 sentinel_list_print(txd->sentinel_list, "SENTINEL_LIST (MAIN LIST)");
00443 #endif
00444 txd->sentinel_list_preacquire->num_entries = 0;
00445 for (i=0; i<txd->sentinel_list->num_entries; i++) {
00446 entry = &txd->sentinel_list->entries[i];
00447 if (entry->status & TXC_SENTINEL_ACQUIREONRETRY) {
00448 enlist_sentinel(txd->sentinel_list_preacquire,
00449 entry->sentinel,
00450 0 & ~TXC_SENTINEL_ACQUIRED);
00451 }
00452 }
00453 sentinel_list_sort(txd->sentinel_list_preacquire);
00454
00455
00456
00457
00458
00459
00460 sentinel_list_release(txd->sentinel_list, 0);
00461 #ifdef _TXC_DEBUG_BUILD
00462 sentinel_list_print(txd->sentinel_list_preacquire,
00463 "SENTINEL LIST (PREACQUIRE LIST)");
00464 #endif
00465 txc_sentinel_list_init(txd->sentinel_list);
00466 txd->sentinelmgr_undo_action_registered = 0;
00467 txd->sentinelmgr_commit_action_registered = 0;
00468 backoff(txd);
00469 sentinel_list_acquire(txd, txd->sentinel_list_preacquire);
00470 }
00471
00472
00473 static
00474 void
00475 sentinelmgr_commit_action(void *args, int *result)
00476 {
00477 txc_tx_t *txd = (txc_tx_t *) args;
00478 sentinelmgr_transaction_on_complete(txd);
00479
00480 if (result) {
00481 *result = 0;
00482 }
00483 }
00484
00485
00486 static
00487 void
00488 sentinelmgr_undo_action(void *args, int *result)
00489 {
00490 txc_tx_t *txd = (txc_tx_t *) args;
00491
00492 switch (txd->abort_reason) {
00493 case TXC_ABORTREASON_USERABORT:
00494 sentinelmgr_transaction_on_complete(txd);
00495 break;
00496 case TXC_ABORTREASON_TMCONFLICT:
00497 case TXC_ABORTREASON_USERRETRY:
00498 case TXC_ABORTREASON_INCONSISTENCY:
00499 case TXC_ABORTREASON_BUSYSENTINEL:
00500 case TXC_ABORTREASON_BUSYTXLOCK:
00501 sentinelmgr_transaction_before_retry(txd);
00502 break;
00503 default:
00504 TXC_INTERNALERROR("Unknown abort reason\n");
00505
00506 }
00507
00508 if (result) {
00509 *result = 0;
00510 }
00511 }
00512
00513
00514 static inline
00515 void
00516 register_sentinelmgr_commit_action(txc_tx_t *txd)
00517 {
00518 if (txd->sentinelmgr_commit_action_registered == 0) {
00519 txc_tx_register_commit_action(txd,
00520 sentinelmgr_commit_action,
00521 (void *) txd,
00522 NULL,
00523 TXC_SENTINELMGR_COMMIT_ACTION_ORDER);
00524 txd->sentinelmgr_commit_action_registered = 1;
00525 }
00526 }
00527
00528
00529 static inline
00530 void
00531 register_sentinelmgr_undo_action(txc_tx_t *txd)
00532 {
00533 if (txd->sentinelmgr_undo_action_registered == 0) {
00534 txc_tx_register_undo_action(txd,
00535 sentinelmgr_undo_action,
00536 (void *) txd,
00537 NULL,
00538 TXC_SENTINELMGR_UNDO_ACTION_ORDER);
00539 txd->sentinelmgr_undo_action_registered = 1;
00540 }
00541 }
00542
00543
00544 void
00545 txc_sentinel_register_sentinelmgr_commit_action(txc_tx_t *txd)
00546 {
00547 register_sentinelmgr_commit_action(txd);
00548 }
00549
00550
00551 void
00552 txc_sentinel_register_sentinelmgr_undo_action(txc_tx_t *txd)
00553 {
00554 register_sentinelmgr_undo_action(txd);
00555 }
00556
00557
00558 void
00559 txc_sentinel_transaction_postbegin(txc_tx_t *txd)
00560 {
00561
00562
00563
00564
00565
00566 if (txd->sentinel_list->num_entries) {
00567 register_sentinelmgr_commit_action(txd);
00568 register_sentinelmgr_undo_action(txd);
00569 }
00570 }
00571
00572
00573 static inline
00574 txc_result_t
00575 allocate_sentinel_list_entries(txc_sentinel_list_t *la, int extend)
00576 {
00577 if (extend) {
00578
00579 la->size *= 2;
00580 if ((la->entries =
00581 (txc_sentinel_list_entry_t *) REALLOC (la->entries,
00582 la->size * sizeof(txc_sentinel_list_entry_t)))
00583 == NULL)
00584 {
00585 return TXC_R_NOMEMORY;
00586 }
00587 } else {
00588
00589 if ((la->entries =
00590 (txc_sentinel_list_entry_t *) MALLOC (la->size * sizeof(txc_sentinel_list_entry_t)))
00591 == NULL)
00592 {
00593 return TXC_R_NOMEMORY;
00594 }
00595 }
00596 return TXC_R_SUCCESS;
00597 }
00598
00599
00600 static inline
00601 txc_result_t
00602 deallocate_sentinel_list_entries(txc_sentinel_list_t *la)
00603 {
00604 FREE(la->entries);
00605 return TXC_R_SUCCESS;
00606 }
00607
00608
00617 txc_result_t
00618 txc_sentinel_list_create(txc_sentinelmgr_t *sentinelmgr,
00619 txc_sentinel_list_t **sentinel_list)
00620 {
00621 txc_result_t result;
00622
00623 if ((*sentinel_list = (txc_sentinel_list_t *) MALLOC(sizeof(txc_sentinel_list_t)))
00624 == NULL)
00625 {
00626 return TXC_R_NOMEMORY;
00627 }
00628
00629 (*sentinel_list)->manager = sentinelmgr;
00630 (*sentinel_list)->num_entries = 0;
00631 (*sentinel_list)->size = TXC_SENTINEL_LIST_SIZE;
00632
00633 if ((result = allocate_sentinel_list_entries(*sentinel_list, 0))
00634 != TXC_R_SUCCESS)
00635 {
00636 FREE(*sentinel_list);
00637 return result;
00638 }
00639
00640 return TXC_R_SUCCESS;
00641 }
00642
00650 txc_result_t
00651 txc_sentinel_list_init(txc_sentinel_list_t *sentinel_list)
00652 {
00653 sentinel_list->num_entries = 0;
00654
00655 return TXC_R_SUCCESS;
00656 }
00657
00668 txc_result_t
00669 txc_sentinel_list_destroy(txc_sentinel_list_t **sentinel_list)
00670 {
00671 txc_result_t result;
00672
00673 if ((result = deallocate_sentinel_list_entries(*sentinel_list))
00674 != TXC_R_SUCCESS)
00675 {
00676 return result;
00677 }
00678 FREE(*sentinel_list);
00679 *sentinel_list = NULL;
00680 return TXC_R_SUCCESS;
00681 }
00682
00683
00694 static inline
00695 txc_result_t
00696 enlist_sentinel(txc_sentinel_list_t *sentinel_list,
00697 txc_sentinel_t *sentinel,
00698 txc_result_t status)
00699 {
00700 txc_result_t ret;
00701
00702 if (sentinel_list->num_entries == sentinel_list->size) {
00703 if ((ret = allocate_sentinel_list_entries(sentinel_list, 1))
00704 != TXC_R_SUCCESS)
00705 {
00706 return ret;
00707 }
00708 }
00709
00710 sentinel_list->entries[sentinel_list->num_entries].sentinel = sentinel;
00711 sentinel_list->entries[sentinel_list->num_entries].status = status;
00712 sentinel_list->num_entries++;
00713
00714 return TXC_R_SUCCESS;
00715 }
00716
00717
00729 txc_result_t
00730 txc_sentinel_enlist(txc_tx_t *txd, txc_sentinel_t *sentinel, int flags)
00731 {
00732 int acquire_on_retry;
00733
00734 acquire_on_retry = (flags & TXC_SENTINEL_ACQUIREONRETRY) > 0 ?
00735 TXC_SENTINEL_ACQUIREONRETRY : 0;
00736
00737 TXC_MUTEX_LOCK(&sentinel->synch_mutex);
00738 sentinel_attach(sentinel);
00739 TXC_MUTEX_UNLOCK(&sentinel->synch_mutex);
00740 enlist_sentinel(txd->sentinel_list, sentinel, acquire_on_retry);
00741 return TXC_R_SUCCESS;
00742 }
00743
00744
00758 txc_result_t
00759 txc_sentinel_tryacquire(txc_tx_t *txd, txc_sentinel_t *sentinel, int flags)
00760 {
00761 int ret;
00762 int num_spin_retries;
00763 int acquire_on_retry;
00764 txc_result_t result;
00765
00766 TXC_ASSERT(sentinel != NULL);
00767 TXC_ASSERT(txd != NULL);
00768 acquire_on_retry = (flags & TXC_SENTINEL_ACQUIREONRETRY) > 0 ?
00769 TXC_SENTINEL_ACQUIREONRETRY : 0;
00770
00771
00772 if (sentinel->owner != txd) {
00773 switch (txc_tx_get_xactstate(txd)) {
00774 case TXC_XACTSTATE_NONTRANSACTIONAL:
00775 TXC_INTERNALERROR("Acquiring a sentinel outside of a transaction not supported\n");
00776
00777 case TXC_XACTSTATE_TRANSACTIONAL_IRREVOCABLE:
00778
00779
00780
00781
00782 result = TXC_R_SUCCESS;
00783 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00784 "ACQUIRE SENTINEL %3d: SUCCESS (GLOCK)\n",
00785 sentinel->id);
00786 break;
00787 case TXC_XACTSTATE_TRANSACTIONAL_RETRYABLE:
00788 register_sentinelmgr_undo_action(txd);
00789 register_sentinelmgr_commit_action(txd);
00790 num_spin_retries = txc_runtime_settings.sentinel_max_spin_retries;
00791 do {
00792 ret = TXC_MUTEX_TRYLOCK(&sentinel->sentinel_mutex);
00793 } while (--num_spin_retries >= 0 && ret != 0);
00794 if (ret == 0) {
00795 TXC_MUTEX_LOCK(&sentinel->synch_mutex);
00796 sentinel_attach(sentinel);
00797 TXC_MUTEX_UNLOCK(&sentinel->synch_mutex);
00798 sentinel->owner = txd;
00799 enlist_sentinel(txd->sentinel_list, sentinel,
00800 TXC_SENTINEL_ACQUIRED |
00801 acquire_on_retry);
00802 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00803 "ACQUIRE SENTINEL %3d: SUCCESS\n",
00804 sentinel->id);
00805 result = TXC_R_SUCCESS;
00806 } else {
00807 TXC_MUTEX_LOCK(&sentinel->synch_mutex);
00808 sentinel_attach(sentinel);
00809 TXC_MUTEX_UNLOCK(&sentinel->synch_mutex);
00810 enlist_sentinel(txd->sentinel_list, sentinel,
00811 acquire_on_retry);
00812 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00813 "ACQUIRE SENTINEL %3d: BUSY\n",
00814 sentinel->id);
00815 result = TXC_R_BUSYSENTINEL;
00816 }
00817 break;
00818 default:
00819 TXC_INTERNALERROR("Unknown transaction state\n");
00820 }
00821 } else {
00822 #ifdef _TXC_DEBUG_BUILD
00823 TXC_ASSERT(txc_sentinel_owner(sentinel) == txd);
00824 TXC_ASSERT(txc_sentinel_is_enlisted(txd, sentinel) == TXC_R_SUCCESS);
00825 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00826 "ACQUIRE SENTINEL %3d: SUCCESS (HAVE IT)\n",
00827 sentinel->id);
00828 #endif
00829 }
00830 return result;
00831 }
00832
00833
00834 static inline
00835 void
00836 backoff(txc_tx_t *txd)
00837 {
00838 useconds_t wait_time;
00839
00840 if (txc_runtime_settings.sentinel_max_backoff_time>0) {
00841 wait_time = (useconds_t) txc_tx_get_forced_retries(txd) * 32;
00842 if (wait_time < txc_runtime_settings.sentinel_max_backoff_time) {
00843 usleep(wait_time);
00844 } else {
00845 usleep(txc_runtime_settings.sentinel_max_backoff_time);
00846 }
00847 }
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 static inline
00859 void
00860 sentinel_print(void *addr)
00861 {
00862 txc_sentinel_t *sentinel = (txc_sentinel_t *) addr;
00863
00864 fprintf(TXC_DEBUG_OUT, "SENTINEL %3d: owner = %p (TID = %u)\n",
00865 sentinel->id,
00866 sentinel->owner,
00867 sentinel->owner->tid);
00868
00869 }
00870
00871 static inline
00872 void
00873 sentinel_list_print(txc_sentinel_list_t *sentinel_list, char *heading)
00874 {
00875 int i;
00876 txc_sentinel_list_entry_t *entry;
00877 txc_sentinel_t *sentinel;
00878
00879 if (TXC_DEBUG_SENTINEL) {
00880 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "%s\n", heading);
00881 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "====================================\n");
00882 for (i=0; i<sentinel_list->num_entries; i++) {
00883 entry = &sentinel_list->entries[i];
00884 sentinel = entry->sentinel;
00885 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL,
00886 "SENTINEL %3d: owner = %p (TID = %d) entry_status = %x\n",
00887 sentinel->id,
00888 sentinel->owner,
00889 (sentinel->owner == NULL) ? -1 : sentinel->owner->tid,
00890 entry->status);
00891 }
00892 }
00893 }
00894
00895
00896 void
00897 txc_sentinelmgr_print_pools(txc_sentinelmgr_t *sentinelmgr) {
00898 if (TXC_DEBUG_SENTINEL) {
00899 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "SENTINEL POOL\n");
00900 TXC_DEBUG_PRINT(TXC_DEBUG_SENTINEL, "====================================\n");
00901 txc_pool_print(sentinelmgr->pool_sentinel, sentinel_print, 0);
00902 }
00903 }
00904
00905
00906 txc_tx_t *
00907 txc_sentinel_owner(txc_sentinel_t *sentinel)
00908 {
00909 return sentinel->owner;
00910 }
00911
00912
00913 txc_result_t
00914 txc_sentinel_is_enlisted(txc_tx_t *txd, txc_sentinel_t *sentinel)
00915 {
00916 int i;
00917 txc_sentinel_t *sentinel_iter;
00918
00919
00920
00921
00922
00923 for (i=0; i<txd->sentinel_list->num_entries; i++) {
00924 sentinel_iter = txd->sentinel_list->entries[i].sentinel;
00925 if (sentinel_iter == sentinel) {
00926 return TXC_R_SUCCESS;
00927 }
00928 }
00929 return TXC_R_FAILURE;
00930 }