| 985 | } |
| 986 | |
| 987 | static bool |
| 988 | prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata, |
| 989 | void **p_btkey, prof_gctx_t **p_gctx, bool *p_new_gctx) { |
| 990 | union { |
| 991 | prof_gctx_t *p; |
| 992 | void *v; |
| 993 | } gctx, tgctx; |
| 994 | union { |
| 995 | prof_bt_t *p; |
| 996 | void *v; |
| 997 | } btkey; |
| 998 | bool new_gctx; |
| 999 | |
| 1000 | prof_enter(tsd, tdata); |
| 1001 | if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { |
| 1002 | /* bt has never been seen before. Insert it. */ |
| 1003 | prof_leave(tsd, tdata); |
| 1004 | tgctx.p = prof_gctx_create(tsd_tsdn(tsd), bt); |
| 1005 | if (tgctx.v == NULL) { |
| 1006 | return true; |
| 1007 | } |
| 1008 | prof_enter(tsd, tdata); |
| 1009 | if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { |
| 1010 | gctx.p = tgctx.p; |
| 1011 | btkey.p = &gctx.p->bt; |
| 1012 | if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) { |
| 1013 | /* OOM. */ |
| 1014 | prof_leave(tsd, tdata); |
| 1015 | idalloctm(tsd_tsdn(tsd), gctx.v, NULL, NULL, |
| 1016 | true, true); |
| 1017 | return true; |
| 1018 | } |
| 1019 | new_gctx = true; |
| 1020 | } else { |
| 1021 | new_gctx = false; |
| 1022 | } |
| 1023 | } else { |
| 1024 | tgctx.v = NULL; |
| 1025 | new_gctx = false; |
| 1026 | } |
| 1027 | |
| 1028 | if (!new_gctx) { |
| 1029 | /* |
| 1030 | * Increment nlimbo, in order to avoid a race condition with |
| 1031 | * prof_tctx_destroy()/prof_gctx_try_destroy(). |
| 1032 | */ |
| 1033 | malloc_mutex_lock(tsd_tsdn(tsd), gctx.p->lock); |
| 1034 | gctx.p->nlimbo++; |
| 1035 | malloc_mutex_unlock(tsd_tsdn(tsd), gctx.p->lock); |
| 1036 | new_gctx = false; |
| 1037 | |
| 1038 | if (tgctx.v != NULL) { |
| 1039 | /* Lost race to insert. */ |
| 1040 | idalloctm(tsd_tsdn(tsd), tgctx.v, NULL, NULL, true, |
| 1041 | true); |
| 1042 | } |
| 1043 | } |
| 1044 | prof_leave(tsd, tdata); |
no test coverage detected