this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

workq_kernreturn: Extract initial flags and fix x86_64 assembly arguments

We need to initialize the flags in case we terminate as soon as we're created (because `_pthread_wqthread` requires valid flags).

This also fixes the x86_64 assembly to ensure that the 6th argument is actually passed (for some reason, the old code was causing the 6th argument to be a copy of the 5th). We don't need to specifically use `rbx`, so just use `r` and let the compiler decide what to use.

+31 -17
+31 -17
src/kernel/emulation/linux/bsdthread/workq_kernreturn.c
··· 87 87 // This is horrible, but it may work 88 88 static struct wq_kevent_data* wq_event_pending = NULL; 89 89 90 + static int extract_wq_flags(int priority) { 91 + int flags = 0; 92 + int qos = _pthread_priority_thread_qos(priority); 93 + 94 + // Apple has created a mess of QoS in libdispatch and sometimes libdispatch doesn't set QoS properly when building with configurations Apple (apparently) hasn't tested 95 + // 96 + // we only do this is a hack/workaround until we improve our workqueue/kqueue support to use libdispatch's new SPIs 97 + if (qos == 0) { 98 + qos = 4; // default libdispatch QoS 99 + } 100 + 101 + flags = WQ_FLAG_THREAD_NEWSPI | qos | WQ_FLAG_THREAD_PRIO_QOS; 102 + 103 + if (priority & _PTHREAD_PRIORITY_OVERCOMMIT_FLAG) { 104 + flags |= WQ_FLAG_THREAD_OVERCOMMIT; 105 + } 106 + 107 + return flags; 108 + }; 109 + 90 110 long sys_workq_kernreturn(int options, void* item, int affinity, int prio) 91 111 { 92 112 #ifndef VARIANT_DYLD ··· 133 153 // Semaphore locked state (wait for wakeup) 134 154 me.sem = 0; 135 155 156 + // extract initial flags 157 + // (in case we only get created and used once and then terminate; `_pthread_wqthread` requires a valid `flags` argument) 158 + dthread = _pthread_getspecific_direct(_PTHREAD_TSD_SLOT_PTHREAD_SELF); 159 + prio = _pthread_getspecific_direct(_PTHREAD_TSD_SLOT_PTHREAD_QOS_CLASS); 160 + // doesn't extract `WQ_FLAG_THREAD_KEVENT` if we had it set, but that shouldn't matter 161 + // like i said before, the only case where we actually need these flags to be set here is when the thread is going to die immediately after creation 162 + me.flags = extract_wq_flags(prio); 163 + 136 164 // Enqueue for future WQOPS_QUEUE_REQTHREADS 137 165 TAILQ_INSERT_HEAD(&workq_parked_head, &me, entries); 138 166 ··· 180 208 // arguments are in rdi, rsi, rdx, rcx, r8, r9 181 209 __asm__ __volatile__ ( 182 210 // "int3\n" 183 - "movq %%rbx, %%r8\n" // 5th argument 211 + "movl %3, %%r8d\n" // 5th argument 184 212 "movl %5, %%r9d\n" // 6th argument 185 213 "movq %0, %%rsp\n" 186 214 "subq $32, %%rsp\n" 187 215 "jmpq *%2\n" 188 216 :: "D" (dthread), "S" (thread_self), "a" (wqueue_entry_point), 189 - "b" (me.flags | WQ_FLAG_THREAD_REUSE), "c" ((!terminating && me.event) ? me.event->events : NULL), 217 + "r" (me.flags | WQ_FLAG_THREAD_REUSE), "c" ((!terminating && me.event) ? me.event->events : NULL), 190 218 "r" (terminating ? WORKQ_EXIT_THREAD_NKEVENT : (me.event ? me.event->nevents : 0)), "d" (dthread->stackbottom) 191 219 ); 192 220 #elif defined(__i386__) ··· 219 247 { 220 248 // affinity contains thread count 221 249 222 - int i, flags, qos = _pthread_priority_thread_qos(prio); 223 - 224 - // Apple has created a mess of QoS in libdispatch and sometimes libdispatch doesn't set QoS properly 225 - // when building with configurations Apple (apparently) hasn't tested 226 - // 227 - // we only do this is a hack/workaround until we improve our workqueue/kqueue support to use libdispatch's new SPIs 228 - if (qos == 0) { 229 - qos = 4; // default libdispatch QoS 230 - } 231 - 232 - flags = WQ_FLAG_THREAD_NEWSPI | qos | WQ_FLAG_THREAD_PRIO_QOS; 233 - 234 - if (prio & _PTHREAD_PRIORITY_OVERCOMMIT_FLAG) { 235 - flags |= WQ_FLAG_THREAD_OVERCOMMIT; 236 - } 250 + int i, flags = extract_wq_flags(prio); 237 251 238 252 if (wq_event != NULL) 239 253 flags |= WQ_FLAG_THREAD_KEVENT;