this repo has no description
1
fork

Configure Feed

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

Various fixes that make the Steam updater follow through

+27 -52
+27 -46
src/kernel/emulation/linux/bsdthread/workq_kernreturn.c
··· 9 9 #include <pthread/tsd_private.h> 10 10 #include "../ext/futex.h" 11 11 #include "../simple.h" 12 + #include <sys/queue.h> 13 + #include <os/lock.h> 12 14 13 15 #define WQ_MAX_THREADS 64 14 16 ··· 34 36 #define WQ_FLAG_THREAD_KEVENT 0x00080000 /* thread is response to kevent req */ 35 37 36 38 static int workq_sem = WQ_MAX_THREADS; // max 64 threads in use 37 - static int workq_parked_lock = 1; 39 + static os_unfair_lock workq_parked_lock = OS_UNFAIR_LOCK_INIT; 38 40 // static int workq_parked_threads = 0; // num spawned, but unused threads 39 41 static int workq_parked[WQ_MAX_THREADS]; 40 42 static int workq_parked_prio[WQ_MAX_THREADS]; 41 43 42 - struct parked_thread workq_parked_head = { NULL, NULL }; 44 + TAILQ_HEAD(tailhead, parked_thread) workq_parked_head = TAILQ_HEAD_INITIALIZER(workq_parked_head); 45 + 46 + struct parked_thread 47 + { 48 + int sem, flags; 49 + struct wq_kevent_data* event; 50 + TAILQ_ENTRY(parked_thread) entries; 51 + }; 43 52 44 53 extern void* pthread_get_stackaddr_np(void* pth); 45 54 ··· 51 60 long tv_sec; 52 61 long tv_nsec; 53 62 }; 63 + 64 + void __attribute__((weak)) os_unfair_lock_unlock(os_unfair_lock_t lock) {} 65 + void __attribute__((weak)) os_unfair_lock_lock(os_unfair_lock_t lock) {} 54 66 55 67 //void* __attribute__((weak)) __attribute__((visibility("default"))) pthread_getspecific(unsigned long key) { return NULL; } 56 68 //int __attribute__((weak)) __attribute__((visibility("default"))) pthread_setspecific(unsigned long key, const void* value) { return 1; } ··· 100 112 struct parked_thread me; 101 113 void* pth; 102 114 103 - sem_down(&workq_parked_lock, -1); 115 + os_unfair_lock_lock(&workq_parked_lock); 104 116 105 117 // Semaphore locked state (wait for wakeup) 106 118 me.sem = 0; 107 119 108 120 // Enqueue for future WQOPS_QUEUE_REQTHREADS 109 - list_add(&workq_parked_head, &me); 121 + TAILQ_INSERT_HEAD(&workq_parked_head, &me, entries); 110 122 111 123 // Decrease the amount of running threads 112 124 sem_up(&workq_sem); 113 125 114 - sem_up(&workq_parked_lock); 126 + os_unfair_lock_unlock(&workq_parked_lock); 115 127 116 128 // Wait until someone calls WQOPS_QUEUE_REQTHREADS 117 129 // and wakes us up ··· 119 131 { 120 132 // Make sure we haven't just been woken up before locking the queue 121 133 // and remove us from the queue if not. 122 - sem_down(&workq_parked_lock, -1); 134 + os_unfair_lock_lock(&workq_parked_lock); 123 135 124 136 if (me.sem > 0) 125 137 { 126 - sem_up(&workq_parked_lock); 138 + os_unfair_lock_unlock(&workq_parked_lock); 127 139 goto wakeup; 128 140 } 129 141 130 - list_remove(&workq_parked_head, &me); 142 + TAILQ_REMOVE(&workq_parked_head, &me, entries); 131 143 132 - sem_up(&workq_parked_lock); 144 + os_unfair_lock_unlock(&workq_parked_lock); 133 145 134 146 // Let the thread terminate (libc will call pthread_exit) 135 147 return 0; ··· 205 217 // Increase the amount of running threads 206 218 sem_down(&workq_sem, -1); 207 219 208 - sem_down(&workq_parked_lock, -1); 220 + os_unfair_lock_lock(&workq_parked_lock); 209 221 210 - if (workq_parked_head.next != NULL) 222 + if (workq_parked_head.tqh_first != NULL) 211 223 { 212 224 struct parked_thread* thread; 213 225 214 - thread = workq_parked_head.next; 226 + thread = workq_parked_head.tqh_first; 215 227 216 228 // Resume an existing thread 217 229 // __simple_printf("Resuming thread %d\n", id); ··· 220 232 thread->event = wq_event; 221 233 222 234 // Dequeue 223 - list_remove(&workq_parked_head, thread); 235 + TAILQ_REMOVE(&workq_parked_head, thread, entries); 224 236 225 237 // Resume the thread 226 238 sem_up(&thread->sem); 227 - sem_up(&workq_parked_lock); 239 + os_unfair_lock_unlock(&workq_parked_lock); 228 240 229 241 continue; 230 242 } 231 243 232 - sem_up(&workq_parked_lock); 244 + os_unfair_lock_unlock(&workq_parked_lock); 233 245 234 246 // __simple_printf("Spawning a new thread, nevents=%d\n", (wq_event != NULL) ? wq_event->nevents : -1); 235 247 wq_event_pending = wq_event; ··· 285 297 *sem = 1; 286 298 __linux_futex(sem, FUTEX_WAKE, 1, NULL, 0, 0); 287 299 } 288 - } 289 - 290 - static void list_add(struct parked_thread* head, struct parked_thread* item) 291 - { 292 - if (head->next != NULL) 293 - { 294 - item->prev = head->next->prev; 295 - item->next = head->next; 296 - head->next->prev = item; 297 - } 298 - else 299 - { 300 - item->next = NULL; 301 - item->prev = NULL; 302 - } 303 - head->next = item; 304 - 305 - if (head->prev == NULL) 306 - head->prev = item; 307 - } 308 - 309 - static void list_remove(struct parked_thread* head, struct parked_thread* item) 310 - { 311 - if (item->prev != NULL) 312 - item->prev->next = item->next; 313 - if (item->next != NULL) 314 - item->next->prev = item->prev; 315 - if (head->next == item) 316 - head->next = item->next; 317 - if (head->prev == item) 318 - head->prev = item->prev; 319 300 } 320 301 321 302 #define __PTHREAD_PRIORITY_CBIT_USER_INTERACTIVE 0x20
-6
src/kernel/emulation/linux/bsdthread/workq_kernreturn.h
··· 13 13 int sem; 14 14 }; 15 15 16 - struct parked_thread 17 - { 18 - struct parked_thread *prev, *next; 19 - int sem, flags; 20 - struct wq_kevent_data* event; 21 - }; 22 16 struct timespec; 23 17 24 18 long sys_workq_kernreturn(int options, void* item, int affinity, int prio);