+#if defined(THREADED_RTS)
+ // In threaded mode, we'll use WHITEHOLE to lock the selector
+ // thunk while we evaluate it.
+ {
+ info_ptr = (StgInfoTable *)xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info_ptr == (W_)&stg_WHITEHOLE_info) {
+ do {
+ info_ptr = xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ } while (info_ptr == (W_)&stg_WHITEHOLE_info);
+ goto bale_out;
+ }
+ // make sure someone else didn't get here first
+ if (INFO_PTR_TO_STRUCT(info_ptr)->type != THUNK_SELECTOR) {
+ goto bale_out;
+ }
+ }
+#else
+ // Save the real info pointer (NOTE: not the same as get_itbl()).
+ info_ptr = (StgWord)p->header.info;