| 717 | } |
| 718 | |
| 719 | static bool |
| 720 | prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata, |
| 721 | void **p_btkey, prof_gctx_t **p_gctx, bool *p_new_gctx) { |
| 722 | union { |
| 723 | prof_gctx_t *p; |
| 724 | void *v; |
| 725 | } gctx, tgctx; |
| 726 | union { |
| 727 | prof_bt_t *p; |
| 728 | void *v; |
| 729 | } btkey; |
| 730 | bool new_gctx; |
| 731 | |
| 732 | prof_enter(tsd, tdata); |
| 733 | if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { |
| 734 | /* bt has never been seen before. Insert it. */ |
| 735 | prof_leave(tsd, tdata); |
| 736 | tgctx.p = prof_gctx_create(tsd_tsdn(tsd), bt); |
| 737 | if (tgctx.v == NULL) { |
| 738 | return true; |
| 739 | } |
| 740 | prof_enter(tsd, tdata); |
| 741 | if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { |
| 742 | gctx.p = tgctx.p; |
| 743 | btkey.p = &gctx.p->bt; |
| 744 | if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) { |
| 745 | /* OOM. */ |
| 746 | prof_leave(tsd, tdata); |
| 747 | idalloctm(tsd_tsdn(tsd), gctx.v, NULL, NULL, |
| 748 | true, true); |
| 749 | return true; |
| 750 | } |
| 751 | new_gctx = true; |
| 752 | } else { |
| 753 | new_gctx = false; |
| 754 | } |
| 755 | } else { |
| 756 | tgctx.v = NULL; |
| 757 | new_gctx = false; |
| 758 | } |
| 759 | |
| 760 | if (!new_gctx) { |
| 761 | /* |
| 762 | * Increment nlimbo, in order to avoid a race condition with |
| 763 | * prof_tctx_destroy()/prof_gctx_try_destroy(). |
| 764 | */ |
| 765 | malloc_mutex_lock(tsd_tsdn(tsd), gctx.p->lock); |
| 766 | gctx.p->nlimbo++; |
| 767 | malloc_mutex_unlock(tsd_tsdn(tsd), gctx.p->lock); |
| 768 | new_gctx = false; |
| 769 | |
| 770 | if (tgctx.v != NULL) { |
| 771 | /* Lost race to insert. */ |
| 772 | idalloctm(tsd_tsdn(tsd), tgctx.v, NULL, NULL, true, |
| 773 | true); |
| 774 | } |
| 775 | } |
| 776 | prof_leave(tsd, tdata); |
no test coverage detected