| 1050 | } |
| 1051 | |
| 1052 | prof_tctx_t * |
| 1053 | prof_lookup(tsd_t *tsd, prof_bt_t *bt) { |
| 1054 | union { |
| 1055 | prof_tctx_t *p; |
| 1056 | void *v; |
| 1057 | } ret; |
| 1058 | prof_tdata_t *tdata; |
| 1059 | bool not_found; |
| 1060 | |
| 1061 | cassert(config_prof); |
| 1062 | |
| 1063 | tdata = prof_tdata_get(tsd, false); |
| 1064 | if (tdata == NULL) { |
| 1065 | return NULL; |
| 1066 | } |
| 1067 | |
| 1068 | malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock); |
| 1069 | not_found = ckh_search(&tdata->bt2tctx, bt, NULL, &ret.v); |
| 1070 | if (!not_found) { /* Note double negative! */ |
| 1071 | ret.p->prepared = true; |
| 1072 | } |
| 1073 | malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock); |
| 1074 | if (not_found) { |
| 1075 | void *btkey; |
| 1076 | prof_gctx_t *gctx; |
| 1077 | bool new_gctx, error; |
| 1078 | |
| 1079 | /* |
| 1080 | * This thread's cache lacks bt. Look for it in the global |
| 1081 | * cache. |
| 1082 | */ |
| 1083 | if (prof_lookup_global(tsd, bt, tdata, &btkey, &gctx, |
| 1084 | &new_gctx)) { |
| 1085 | return NULL; |
| 1086 | } |
| 1087 | |
| 1088 | /* Link a prof_tctx_t into gctx for this thread. */ |
| 1089 | ret.v = iallocztm(tsd_tsdn(tsd), sizeof(prof_tctx_t), |
| 1090 | sz_size2index(sizeof(prof_tctx_t)), false, NULL, true, |
| 1091 | arena_ichoose(tsd, NULL), true); |
| 1092 | if (ret.p == NULL) { |
| 1093 | if (new_gctx) { |
| 1094 | prof_gctx_try_destroy(tsd, tdata, gctx, tdata); |
| 1095 | } |
| 1096 | return NULL; |
| 1097 | } |
| 1098 | ret.p->tdata = tdata; |
| 1099 | ret.p->thr_uid = tdata->thr_uid; |
| 1100 | ret.p->thr_discrim = tdata->thr_discrim; |
| 1101 | memset(&ret.p->cnts, 0, sizeof(prof_cnt_t)); |
| 1102 | ret.p->gctx = gctx; |
| 1103 | ret.p->tctx_uid = tdata->tctx_uid_next++; |
| 1104 | ret.p->prepared = true; |
| 1105 | ret.p->state = prof_tctx_state_initializing; |
| 1106 | malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock); |
| 1107 | error = ckh_insert(tsd, &tdata->bt2tctx, btkey, ret.v); |
| 1108 | malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock); |
| 1109 | if (error) { |
no test coverage detected