0000: 23 69 6e 63 6c 75 64 65 20 22 74 68 72 65 61 64 #include "thread
0010: 2e 68 22 0a 0a 0a 23 69 66 20 49 4e 54 45 52 46 .h"...#if INTERF
0020: 41 43 45 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 ACE.#include <st
0030: 64 69 6e 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 dint.h>.#include
0040: 20 3c 73 74 64 64 65 66 2e 68 3e 0a 23 69 6e 63 <stddef.h>.#inc
0050: 6c 75 64 65 20 3c 73 74 64 6e 6f 72 65 74 75 72 lude <stdnoretur
0060: 6e 2e 68 3e 0a 0a 74 79 70 65 64 65 66 20 69 6e n.h>..typedef in
0070: 74 20 74 6c 73 5f 6b 65 79 3b 0a 0a 23 64 65 66 t tls_key;..#def
0080: 69 6e 65 20 54 4c 53 5f 4d 41 58 20 33 32 0a 0a ine TLS_MAX 32..
0090: 2f 2a 2a 0a 20 2a 20 5c 62 72 69 65 66 20 52 65 /**. * \brief Re
00a0: 70 72 65 73 65 6e 74 61 74 69 6f 6e 20 6f 66 20 presentation of
00b0: 61 20 6b 65 72 6e 65 6c 20 74 68 72 65 61 64 2e a kernel thread.
00c0: 0a 20 2a 2f 0a 73 74 72 75 63 74 20 74 68 72 65 . */.struct thre
00d0: 61 64 5f 74 20 7b 0a 09 2f 2a 20 52 75 6e 74 69 ad_t {../* Runti
00e0: 6d 65 20 64 61 74 61 20 2a 2f 0a 0a 09 2f 2a 2a me data */.../**
00f0: 20 54 68 72 65 61 64 20 6c 6f 63 61 6c 20 73 74 Thread local st
0100: 6f 72 61 67 65 20 70 6f 69 6e 74 65 72 73 20 2a orage pointers *
0110: 2f 0a 09 76 6f 69 64 20 2a 20 74 6c 73 5b 54 4c /..void * tls[TL
0120: 53 5f 4d 41 58 5d 3b 0a 09 2f 2a 2a 20 41 72 63 S_MAX];../** Arc
0130: 68 69 74 65 63 74 75 72 65 20 64 65 70 65 6e 64 hitecture depend
0140: 65 6e 74 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 09 ent context */..
0150: 61 72 63 68 5f 63 6f 6e 74 65 78 74 5f 74 20 63 arch_context_t c
0160: 6f 6e 74 65 78 74 3b 0a 09 2f 2a 2a 20 50 72 6f ontext;../** Pro
0170: 63 65 73 73 20 61 73 73 6f 63 69 61 74 65 64 20 cess associated
0180: 77 69 74 68 20 74 68 69 73 20 74 68 72 65 61 64 with this thread
0190: 20 2a 2f 0a 09 70 72 6f 63 65 73 73 5f 74 20 2a */..process_t *
01a0: 20 70 72 6f 63 65 73 73 3b 0a 0a 09 2f 2a 20 54 process;.../* T
01b0: 68 72 65 61 64 20 43 50 55 20 75 73 61 67 65 20 hread CPU usage
01c0: 2a 2f 0a 09 69 6e 74 20 61 63 63 74 3b 0a 09 73 */..int acct;..s
01d0: 74 72 75 63 74 20 7b 0a 09 09 74 69 6d 65 72 73 truct {...timers
01e0: 70 65 63 5f 74 20 74 73 74 61 72 74 3b 0a 09 09 pec_t tstart;...
01f0: 74 69 6d 65 72 73 70 65 63 5f 74 20 74 6c 65 6e timerspec_t tlen
0200: 3b 0a 09 7d 20 61 63 63 74 73 5b 36 34 5d 3b 0a ;..} accts[64];.
0210: 09 74 69 6d 65 72 73 70 65 63 5f 74 20 70 65 72 .timerspec_t per
0220: 69 6f 64 3b 0a 09 74 69 6d 65 72 73 70 65 63 5f iod;..timerspec_
0230: 74 20 75 73 61 67 65 3b 0a 09 74 69 6d 65 72 73 t usage;..timers
0240: 70 65 63 5f 74 20 70 72 65 65 6d 70 74 3b 0a 0a pec_t preempt;..
0250: 09 2f 2a 2a 20 43 75 72 72 65 6e 74 20 74 68 72 ./** Current thr
0260: 65 61 64 20 73 74 61 74 65 20 2a 2f 0a 09 74 73 ead state */..ts
0270: 74 61 74 65 20 73 74 61 74 65 3b 0a 09 2f 2a 2a tate state;../**
0280: 20 54 68 72 65 61 64 20 70 72 69 6f 72 69 74 79 Thread priority
0290: 20 2a 2f 0a 09 74 70 72 69 6f 72 69 74 79 20 70 */..tpriority p
02a0: 72 69 6f 72 69 74 79 3b 0a 09 2f 2a 2a 20 53 65 riority;../** Se
02b0: 74 20 69 66 20 74 68 65 20 74 68 72 65 61 64 20 t if the thread
02c0: 68 61 73 20 62 65 65 6e 20 69 6e 74 65 72 72 75 has been interru
02d0: 70 74 65 64 20 2a 2f 0a 09 69 6e 74 20 69 6e 74 pted */..int int
02e0: 65 72 72 75 70 74 65 64 3b 0a 09 2f 2a 2a 20 49 errupted;../** I
02f0: 66 20 73 65 74 2c 20 69 6e 64 69 63 61 74 65 73 f set, indicates
0300: 20 77 68 69 63 68 20 69 6e 74 65 72 72 75 70 74 which interrupt
0310: 5f 6d 6f 6e 69 74 6f 72 5f 74 20 77 65 27 72 65 _monitor_t we're
0320: 20 77 61 69 74 69 6e 67 20 66 6f 72 20 2a 2f 0a waiting for */.
0330: 09 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 .interrupt_monit
0340: 6f 72 5f 74 20 2a 20 77 61 69 74 69 6e 67 66 6f or_t * waitingfo
0350: 72 3b 0a 09 2f 2a 2a 20 49 66 20 73 65 74 2c 20 r;../** If set,
0360: 69 6e 64 69 63 61 74 65 73 20 77 68 69 63 68 20 indicates which
0370: 69 6e 74 65 72 72 75 70 74 5f 6d 6f 6e 69 74 6f interrupt_monito
0380: 72 5f 74 20 77 65 27 72 65 20 73 6c 65 65 70 69 r_t we're sleepi
0390: 6e 67 20 6f 6e 20 2a 2f 0a 09 69 6e 74 65 72 72 ng on */..interr
03a0: 75 70 74 5f 6d 6f 6e 69 74 6f 72 5f 74 20 2a 20 upt_monitor_t *
03b0: 73 6c 65 65 70 69 6e 67 6f 6e 3b 0a 0a 09 2f 2a sleepingon;.../*
03c0: 2a 20 54 68 72 65 61 64 20 6e 61 6d 65 20 2a 2f * Thread name */
03d0: 0a 09 63 68 61 72 20 2a 20 6e 61 6d 65 3b 0a 0a ..char * name;..
03e0: 09 2f 2a 2a 20 54 68 72 65 61 64 20 6c 6f 63 6b ./** Thread lock
03f0: 20 2a 2f 0a 09 6d 6f 6e 69 74 6f 72 5f 74 20 6c */..monitor_t l
0400: 6f 63 6b 5b 31 5d 3b 0a 0a 09 2f 2a 2a 20 52 65 ock[1];.../** Re
0410: 74 75 72 6e 20 76 61 6c 75 65 20 66 6f 72 20 74 turn value for t
0420: 68 72 65 61 64 5f 6a 6f 69 6e 20 2a 2f 0a 09 76 hread_join */..v
0430: 6f 69 64 20 2a 20 72 65 74 76 61 6c 3b 0a 0a 09 oid * retval;...
0440: 2f 2a 2a 20 54 68 72 65 61 64 20 71 75 65 75 65 /** Thread queue
0450: 20 6e 65 78 74 20 74 68 72 65 61 64 20 2a 2f 0a next thread */.
0460: 09 74 68 72 65 61 64 5f 74 20 2a 6e 65 78 74 3b .thread_t *next;
0470: 0a 09 2f 2a 2a 20 54 68 72 65 61 64 20 71 75 65 ../** Thread que
0480: 75 65 20 70 72 65 76 20 74 68 72 65 61 64 20 2a ue prev thread *
0490: 2f 0a 09 74 68 72 65 61 64 5f 74 20 2a 70 72 65 /..thread_t *pre
04a0: 76 3b 0a 7d 3b 0a 0a 2f 2a 2a 20 54 68 72 65 61 v;.};../** Threa
04b0: 64 20 73 74 61 74 65 20 2a 2f 0a 65 6e 75 6d 20 d state */.enum
04c0: 74 73 74 61 74 65 20 7b 0a 09 2f 2a 2a 20 54 68 tstate {../** Th
04d0: 72 65 61 64 20 69 73 20 6e 65 77 20 2a 2f 0a 09 read is new */..
04e0: 54 48 52 45 41 44 5f 4e 45 57 2c 0a 09 2f 2a 2a THREAD_NEW,../**
04f0: 20 54 68 72 65 61 64 20 69 73 20 72 75 6e 6e 61 Thread is runna
0500: 62 6c 65 20 2a 2f 0a 09 54 48 52 45 41 44 5f 52 ble */..THREAD_R
0510: 55 4e 4e 41 42 4c 45 2c 0a 09 2f 2a 2a 20 54 68 UNNABLE,../** Th
0520: 72 65 61 64 20 69 73 20 72 75 6e 6e 69 6e 67 20 read is running
0530: 2a 2f 0a 09 54 48 52 45 41 44 5f 52 55 4e 4e 49 */..THREAD_RUNNI
0540: 4e 47 2c 0a 09 2f 2a 2a 20 54 68 72 65 61 64 20 NG,../** Thread
0550: 69 73 20 73 6c 65 65 70 69 6e 67 20 2a 2f 0a 09 is sleeping */..
0560: 54 48 52 45 41 44 5f 53 4c 45 45 50 49 4e 47 2c THREAD_SLEEPING,
0570: 0a 09 2f 2a 2a 20 54 68 72 65 61 64 20 69 73 20 ../** Thread is
0580: 74 65 72 6d 69 6e 61 74 65 64 20 2a 2f 0a 09 54 terminated */..T
0590: 48 52 45 41 44 5f 54 45 52 4d 49 4e 41 54 45 44 HREAD_TERMINATED
05a0: 0a 7d 3b 0a 0a 2f 2a 2a 20 54 68 72 65 61 64 20 .};../** Thread
05b0: 70 72 69 6f 72 69 74 79 20 2a 2f 0a 65 6e 75 6d priority */.enum
05c0: 20 74 70 72 69 6f 72 69 74 79 20 7b 0a 09 2f 2a tpriority {../*
05d0: 2a 20 54 68 72 65 61 64 20 69 6e 74 65 72 72 75 * Thread interru
05e0: 70 74 20 70 72 69 6f 72 69 74 79 20 2a 2f 0a 09 pt priority */..
05f0: 54 48 52 45 41 44 5f 49 4e 54 45 52 52 55 50 54 THREAD_INTERRUPT
0600: 20 3d 20 30 2c 0a 09 2f 2a 2a 20 54 68 72 65 61 = 0,../** Threa
0610: 64 20 6e 6f 72 6d 61 6c 20 70 72 69 6f 72 69 74 d normal priorit
0620: 79 20 2a 2f 0a 09 54 48 52 45 41 44 5f 4e 4f 52 y */..THREAD_NOR
0630: 4d 41 4c 2c 0a 09 2f 2a 2a 20 54 68 72 65 61 64 MAL,../** Thread
0640: 20 69 64 6c 65 20 70 72 69 6f 72 69 74 79 20 2a idle priority *
0650: 2f 0a 09 54 48 52 45 41 44 5f 49 44 4c 45 2c 0a /..THREAD_IDLE,.
0660: 09 2f 2a 2a 20 54 68 72 65 61 64 20 69 6e 74 65 ./** Thread inte
0670: 72 72 75 70 74 20 70 72 69 6f 72 69 74 79 20 63 rrupt priority c
0680: 6f 75 6e 74 20 2a 2f 0a 09 54 48 52 45 41 44 5f ount */..THREAD_
0690: 50 52 49 4f 52 49 54 49 45 53 0a 7d 3b 0a 0a 23 PRIORITIES.};..#
06a0: 69 66 6e 64 65 66 20 62 61 72 72 69 65 72 0a 23 ifndef barrier.#
06b0: 64 65 66 69 6e 65 20 62 61 72 72 69 65 72 28 29 define barrier()
06c0: 20 61 73 6d 20 76 6f 6c 61 74 69 6c 65 28 22 22 asm volatile(""
06d0: 3a 20 3a 20 3a 22 6d 65 6d 6f 72 79 22 29 0a 23 : : :"memory").#
06e0: 65 6e 64 69 66 0a 0a 74 79 70 65 64 65 66 20 76 endif..typedef v
06f0: 6f 69 64 20 2a 20 28 2a 74 68 72 65 61 64 5f 66 oid * (*thread_f
0700: 75 6e 63 5f 74 29 28 76 6f 69 64 20 2a 20 61 72 unc_t)(void * ar
0710: 67 29 3b 0a 0a 73 74 72 75 63 74 20 74 68 72 65 g);..struct thre
0720: 61 64 5f 70 6f 6f 6c 5f 74 20 7b 0a 09 71 75 65 ad_pool_t {..que
0730: 75 65 5f 74 20 2a 20 71 75 65 75 65 3b 0a 09 74 ue_t * queue;..t
0740: 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 hread_t * thread
0750: 3b 0a 7d 3b 0a 0a 23 65 6e 64 69 66 0a 0a 69 6e ;.};..#endif..in
0760: 74 20 70 72 65 65 6d 70 74 3b 0a 73 74 61 74 69 t preempt;.stati
0770: 63 20 74 6c 73 5f 6b 65 79 20 74 6c 73 5f 6e 65 c tls_key tls_ne
0780: 78 74 20 3d 20 31 3b 0a 0a 2f 2a 2a 20 0a 20 2a xt = 1;../** . *
0790: 20 47 65 74 20 74 68 65 20 6e 65 78 74 20 54 4c Get the next TL
07a0: 53 20 6b 65 79 0a 20 2a 20 5c 72 65 74 75 72 6e S key. * \return
07b0: 20 4e 65 78 74 20 6b 65 79 0a 20 2a 2f 0a 69 6e Next key. */.in
07c0: 74 20 74 6c 73 5f 67 65 74 5f 6b 65 79 28 29 0a t tls_get_key().
07d0: 7b 0a 09 72 65 74 75 72 6e 20 61 72 63 68 5f 61 {..return arch_a
07e0: 74 6f 6d 69 63 5f 70 6f 73 74 69 6e 63 28 26 74 tomic_postinc(&t
07f0: 6c 73 5f 6e 65 78 74 29 3b 0a 7d 0a 0a 2f 2a 2a ls_next);.}../**
0800: 0a 20 2a 20 53 65 74 20 74 68 65 20 74 68 72 65 . * Set the thre
0810: 61 64 20 6c 6f 63 61 6c 20 64 61 74 61 20 67 69 ad local data gi
0820: 76 65 6e 20 62 79 20 74 68 65 20 6b 65 79 2e 0a ven by the key..
0830: 20 2a 0a 20 2a 20 5c 61 72 67 20 6b 65 79 20 54 *. * \arg key T
0840: 4c 53 20 6b 65 79 20 72 65 74 72 69 65 76 65 64 LS key retrieved
0850: 20 75 73 69 6e 67 20 5c 72 65 66 20 74 6c 73 5f using \ref tls_
0860: 67 65 74 5f 6b 65 79 0a 20 2a 20 5c 61 72 67 20 get_key. * \arg
0870: 70 20 50 6f 69 6e 74 65 72 20 76 61 6c 75 65 0a p Pointer value.
0880: 20 2a 2f 0a 76 6f 69 64 20 74 6c 73 5f 73 65 74 */.void tls_set
0890: 28 69 6e 74 20 6b 65 79 2c 20 76 6f 69 64 20 2a (int key, void *
08a0: 20 70 29 0a 7b 0a 09 74 68 72 65 61 64 5f 74 20 p).{..thread_t
08b0: 2a 20 74 68 72 65 61 64 20 3d 20 61 72 63 68 5f * thread = arch_
08c0: 67 65 74 5f 74 68 72 65 61 64 28 29 3b 0a 0a 09 get_thread();...
08d0: 63 68 65 63 6b 5f 6e 6f 74 5f 6e 75 6c 6c 28 74 check_not_null(t
08e0: 68 72 65 61 64 2c 20 22 55 6e 61 62 6c 65 20 74 hread, "Unable t
08f0: 6f 20 67 65 74 20 74 68 72 65 61 64 22 29 3b 0a o get thread");.
0900: 09 63 68 65 63 6b 5f 69 6e 74 5f 62 6f 75 6e 64 .check_int_bound
0910: 73 28 6b 65 79 2c 20 31 2c 20 54 4c 53 5f 4d 41 s(key, 1, TLS_MA
0920: 58 2d 31 2c 20 22 54 4c 53 20 6b 65 79 20 6f 75 X-1, "TLS key ou
0930: 74 20 6f 66 20 62 6f 75 6e 64 73 22 29 3b 0a 0a t of bounds");..
0940: 09 74 68 72 65 61 64 2d 3e 74 6c 73 5b 6b 65 79 .thread->tls[key
0950: 5d 20 3d 20 70 3b 0a 7d 0a 0a 2f 2a 2a 0a 20 2a ] = p;.}../**. *
0960: 20 47 65 74 20 74 68 65 20 74 68 72 65 61 64 20 Get the thread
0970: 6c 6f 63 61 6c 20 64 61 74 61 20 67 69 76 65 6e local data given
0980: 20 62 79 20 74 68 65 20 6b 65 79 2e 0a 20 2a 0a by the key.. *.
0990: 20 2a 20 5c 61 72 67 20 6b 65 79 20 54 4c 53 20 * \arg key TLS
09a0: 6b 65 79 20 72 65 74 72 69 65 76 65 64 20 75 73 key retrieved us
09b0: 69 6e 67 20 5c 72 65 66 20 74 6c 73 5f 67 65 74 ing \ref tls_get
09c0: 5f 6b 65 79 0a 20 2a 20 5c 72 65 74 75 72 6e 20 _key. * \return
09d0: 50 6f 69 6e 74 65 72 20 76 61 6c 75 65 0a 20 2a Pointer value. *
09e0: 2f 0a 76 6f 69 64 20 2a 20 74 6c 73 5f 67 65 74 /.void * tls_get
09f0: 28 69 6e 74 20 6b 65 79 29 0a 7b 0a 09 74 68 72 (int key).{..thr
0a00: 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 20 3d ead_t * thread =
0a10: 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 arch_get_thread
0a20: 28 29 3b 0a 0a 09 63 68 65 63 6b 5f 6e 6f 74 5f ();...check_not_
0a30: 6e 75 6c 6c 28 74 68 72 65 61 64 2c 20 22 55 6e null(thread, "Un
0a40: 61 62 6c 65 20 74 6f 20 67 65 74 20 74 68 72 65 able to get thre
0a50: 61 64 22 29 3b 0a 09 63 68 65 63 6b 5f 69 6e 74 ad");..check_int
0a60: 5f 62 6f 75 6e 64 73 28 6b 65 79 2c 20 31 2c 20 _bounds(key, 1,
0a70: 54 4c 53 5f 4d 41 58 2d 31 2c 20 22 54 4c 53 20 TLS_MAX-1, "TLS
0a80: 6b 65 79 20 6f 75 74 20 6f 66 20 62 6f 75 6e 64 key out of bound
0a90: 73 22 29 3b 0a 0a 09 72 65 74 75 72 6e 20 74 68 s");...return th
0aa0: 72 65 61 64 2d 3e 74 6c 73 5b 6b 65 79 5d 3b 0a read->tls[key];.
0ab0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 }..static void t
0ac0: 68 72 65 61 64 5f 6d 61 72 6b 28 76 6f 69 64 20 hread_mark(void
0ad0: 2a 20 70 29 3b 0a 73 74 61 74 69 63 20 76 6f 69 * p);.static voi
0ae0: 64 20 74 68 72 65 61 64 5f 66 69 6e 61 6c 69 7a d thread_finaliz
0af0: 65 28 76 6f 69 64 20 2a 20 70 29 3b 0a 73 74 61 e(void * p);.sta
0b00: 74 69 63 20 73 6c 61 62 5f 74 79 70 65 5f 74 20 tic slab_type_t
0b10: 74 68 72 65 61 64 73 5b 31 5d 20 3d 20 7b 53 4c threads[1] = {SL
0b20: 41 42 5f 54 59 50 45 28 73 69 7a 65 6f 66 28 74 AB_TYPE(sizeof(t
0b30: 68 72 65 61 64 5f 74 29 2c 20 74 68 72 65 61 64 hread_t), thread
0b40: 5f 6d 61 72 6b 2c 20 74 68 72 65 61 64 5f 66 69 _mark, thread_fi
0b50: 6e 61 6c 69 7a 65 29 7d 3b 0a 0a 73 74 61 74 69 nalize)};..stati
0b60: 63 20 73 70 69 6e 5f 74 20 71 75 65 75 65 6c 6f c spin_t queuelo
0b70: 63 6b 3b 0a 0a 2f 2a 2a 0a 20 2a 20 4c 6f 63 6b ck;../**. * Lock
0b80: 20 73 63 68 65 64 75 6c 65 72 0a 20 2a 2f 0a 76 scheduler. */.v
0b90: 6f 69 64 20 73 63 68 65 64 75 6c 65 72 5f 6c 6f oid scheduler_lo
0ba0: 63 6b 28 29 0a 7b 0a 09 73 70 69 6e 5f 6c 6f 63 ck().{..spin_loc
0bb0: 6b 28 26 71 75 65 75 65 6c 6f 63 6b 29 3b 0a 7d k(&queuelock);.}
0bc0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 63 ..static void sc
0bd0: 68 65 64 75 6c 65 72 5f 75 6e 6c 6f 63 6b 28 29 heduler_unlock()
0be0: 0a 7b 0a 09 73 70 69 6e 5f 75 6e 6c 6f 63 6b 28 .{..spin_unlock(
0bf0: 26 71 75 65 75 65 6c 6f 63 6b 29 3b 0a 7d 0a 0a &queuelock);.}..
0c00: 2f 2a 2a 0a 20 2a 20 50 75 74 20 74 68 65 20 67 /**. * Put the g
0c10: 69 76 65 6e 20 74 68 72 65 61 64 20 6f 6e 20 74 iven thread on t
0c20: 68 65 20 68 65 61 64 20 6f 66 20 74 68 65 20 67 he head of the g
0c30: 69 76 65 6e 20 71 75 65 75 65 2c 20 69 6e 20 74 iven queue, in t
0c40: 68 65 20 67 69 76 65 6e 20 73 74 61 74 65 2e 0a he given state..
0c50: 20 2a 20 5c 61 72 67 20 71 75 65 75 65 20 43 75 * \arg queue Cu
0c60: 72 72 65 6e 74 20 71 75 65 75 65 0a 20 2a 20 5c rrent queue. * \
0c70: 61 72 67 20 74 68 72 65 61 64 20 54 68 72 65 61 arg thread Threa
0c80: 64 20 74 6f 20 71 75 65 75 65 0a 20 2a 20 5c 61 d to queue. * \a
0c90: 72 67 20 73 74 61 74 65 20 54 68 72 65 61 64 20 rg state Thread
0ca0: 73 74 61 74 65 0a 20 2a 20 5c 72 65 74 75 72 6e state. * \return
0cb0: 20 4e 65 77 20 71 75 65 75 65 20 68 65 61 64 0a New queue head.
0cc0: 20 2a 2f 0a 74 68 72 65 61 64 5f 74 20 2a 20 74 */.thread_t * t
0cd0: 68 72 65 61 64 5f 70 72 65 71 75 65 75 65 28 74 hread_prequeue(t
0ce0: 68 72 65 61 64 5f 74 20 2a 20 71 75 65 75 65 2c hread_t * queue,
0cf0: 20 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 thread_t * thre
0d00: 61 64 2c 20 74 73 74 61 74 65 20 73 74 61 74 65 ad, tstate state
0d10: 29 0a 7b 0a 09 69 66 20 28 30 20 3d 3d 20 74 68 ).{..if (0 == th
0d20: 72 65 61 64 29 20 7b 0a 09 09 74 68 72 65 61 64 read) {...thread
0d30: 20 3d 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 = arch_get_thre
0d40: 61 64 28 29 3b 0a 09 7d 0a 09 74 68 72 65 61 64 ad();..}..thread
0d50: 2d 3e 73 74 61 74 65 20 3d 20 73 74 61 74 65 3b ->state = state;
0d60: 0a 09 4c 49 53 54 5f 50 52 45 50 45 4e 44 28 71 ..LIST_PREPEND(q
0d70: 75 65 75 65 2c 20 74 68 72 65 61 64 29 3b 0a 09 ueue, thread);..
0d80: 72 65 74 75 72 6e 20 71 75 65 75 65 3b 0a 7d 0a return queue;.}.
0d90: 0a 2f 2a 2a 0a 20 2a 20 50 75 74 20 74 68 65 20 ./**. * Put the
0da0: 67 69 76 65 6e 20 74 68 72 65 61 64 20 6f 6e 20 given thread on
0db0: 74 61 69 6c 20 6f 66 20 74 68 65 20 67 69 76 65 tail of the give
0dc0: 6e 20 71 75 65 75 65 2c 20 69 6e 20 74 68 65 20 n queue, in the
0dd0: 67 69 76 65 6e 20 73 74 61 74 65 2e 0a 20 2a 20 given state.. *
0de0: 5c 61 72 67 20 71 75 65 75 65 20 43 75 72 72 65 \arg queue Curre
0df0: 6e 74 20 71 75 65 75 65 0a 20 2a 20 5c 61 72 67 nt queue. * \arg
0e00: 20 74 68 72 65 61 64 20 54 68 72 65 61 64 20 74 thread Thread t
0e10: 6f 20 71 75 65 75 65 0a 20 2a 20 5c 61 72 67 20 o queue. * \arg
0e20: 73 74 61 74 65 20 54 68 72 65 61 64 20 73 74 61 state Thread sta
0e30: 74 65 0a 20 2a 20 5c 72 65 74 75 72 6e 20 4e 65 te. * \return Ne
0e40: 77 20 71 75 65 75 65 20 68 65 61 64 0a 20 2a 2f w queue head. */
0e50: 0a 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 .thread_t * thre
0e60: 61 64 5f 71 75 65 75 65 28 74 68 72 65 61 64 5f ad_queue(thread_
0e70: 74 20 2a 20 71 75 65 75 65 2c 20 74 68 72 65 61 t * queue, threa
0e80: 64 5f 74 20 2a 20 74 68 72 65 61 64 2c 20 74 73 d_t * thread, ts
0e90: 74 61 74 65 20 73 74 61 74 65 29 0a 7b 0a 09 69 tate state).{..i
0ea0: 66 20 28 30 20 3d 3d 20 74 68 72 65 61 64 29 20 f (0 == thread)
0eb0: 7b 0a 09 09 74 68 72 65 61 64 20 3d 20 61 72 63 {...thread = arc
0ec0: 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 3b 0a h_get_thread();.
0ed0: 09 7d 0a 09 74 68 72 65 61 64 2d 3e 73 74 61 74 .}..thread->stat
0ee0: 65 20 3d 20 73 74 61 74 65 3b 0a 09 4c 49 53 54 e = state;..LIST
0ef0: 5f 41 50 50 45 4e 44 28 71 75 65 75 65 2c 20 74 _APPEND(queue, t
0f00: 68 72 65 61 64 29 3b 0a 09 72 65 74 75 72 6e 20 hread);..return
0f10: 71 75 65 75 65 3b 0a 7d 0a 0a 2f 2a 20 53 69 6d queue;.}../* Sim
0f20: 70 6c 65 20 52 52 20 73 63 68 65 64 75 6c 65 72 ple RR scheduler
0f30: 20 2a 2f 0a 73 74 61 74 69 63 20 47 43 52 4f 4f */.static GCROO
0f40: 54 20 74 68 72 65 61 64 5f 74 20 2a 20 71 75 65 T thread_t * que
0f50: 75 65 5b 54 48 52 45 41 44 5f 50 52 49 4f 52 49 ue[THREAD_PRIORI
0f60: 54 49 45 53 5d 3b 0a 0a 2f 2a 2a 0a 20 2a 20 50 TIES];../**. * P
0f70: 72 65 2d 65 6d 70 74 20 74 68 65 20 63 75 72 72 re-empt the curr
0f80: 65 6e 74 20 74 68 72 65 61 64 2c 20 70 75 74 74 ent thread, putt
0f90: 69 6e 67 20 74 68 65 20 74 68 72 65 61 64 20 6f ing the thread o
0fa0: 6e 74 6f 20 74 68 65 20 68 65 61 64 20 6f 66 20 nto the head of
0fb0: 74 68 65 20 72 75 6e 20 71 75 65 75 65 0a 20 2a the run queue. *
0fc0: 20 5c 72 65 74 75 72 6e 20 31 20 69 66 20 74 68 \return 1 if th
0fd0: 65 20 74 68 72 65 61 64 20 77 61 73 20 70 72 65 e thread was pre
0fe0: 2d 65 6d 70 74 65 64 0a 20 2a 2f 0a 69 6e 74 20 -empted. */.int
0ff0: 74 68 72 65 61 64 5f 70 72 65 65 6d 70 74 28 29 thread_preempt()
1000: 0a 7b 0a 09 74 68 72 65 61 64 5f 74 20 2a 20 74 .{..thread_t * t
1010: 68 69 73 20 3d 20 61 72 63 68 5f 67 65 74 5f 74 his = arch_get_t
1020: 68 72 65 61 64 28 29 3b 0a 09 74 70 72 69 6f 72 hread();..tprior
1030: 69 74 79 20 70 72 69 6f 72 69 74 79 20 3d 20 74 ity priority = t
1040: 68 69 73 2d 3e 70 72 69 6f 72 69 74 79 3b 0a 09 his->priority;..
1050: 73 63 68 65 64 75 6c 65 72 5f 6c 6f 63 6b 28 29 scheduler_lock()
1060: 3b 0a 09 71 75 65 75 65 5b 70 72 69 6f 72 69 74 ;..queue[priorit
1070: 79 5d 20 3d 20 74 68 72 65 61 64 5f 70 72 65 71 y] = thread_preq
1080: 75 65 75 65 28 71 75 65 75 65 5b 70 72 69 6f 72 ueue(queue[prior
1090: 69 74 79 5d 2c 20 74 68 69 73 2c 20 54 48 52 45 ity], this, THRE
10a0: 41 44 5f 52 55 4e 4e 41 42 4c 45 29 3b 0a 09 72 AD_RUNNABLE);..r
10b0: 65 74 75 72 6e 20 74 68 72 65 61 64 5f 73 63 68 eturn thread_sch
10c0: 65 64 75 6c 65 28 29 3b 0a 7d 0a 0a 2f 2a 2a 0a edule();.}../**.
10d0: 20 2a 20 50 72 65 2d 65 6d 70 74 20 74 68 65 20 * Pre-empt the
10e0: 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 2c 20 current thread,
10f0: 70 75 74 74 69 6e 67 20 74 68 65 20 74 68 72 65 putting the thre
1100: 61 64 20 6f 6e 74 6f 20 74 68 65 20 68 65 61 64 ad onto the head
1110: 20 6f 66 20 74 68 65 20 72 75 6e 20 71 75 65 75 of the run queu
1120: 65 0a 20 2a 20 5c 72 65 74 75 72 6e 20 31 20 69 e. * \return 1 i
1130: 66 20 74 68 65 20 74 68 72 65 61 64 20 77 61 73 f the thread was
1140: 20 70 72 65 2d 65 6d 70 74 65 64 0a 20 2a 2f 0a pre-empted. */.
1150: 69 6e 74 20 74 68 72 65 61 64 5f 79 69 65 6c 64 int thread_yield
1160: 28 29 0a 7b 0a 09 74 68 72 65 61 64 5f 74 20 2a ().{..thread_t *
1170: 20 74 68 69 73 20 3d 20 61 72 63 68 5f 67 65 74 this = arch_get
1180: 5f 74 68 72 65 61 64 28 29 3b 0a 09 74 70 72 69 _thread();..tpri
1190: 6f 72 69 74 79 20 70 72 69 6f 72 69 74 79 20 3d ority priority =
11a0: 20 74 68 69 73 2d 3e 70 72 69 6f 72 69 74 79 3b this->priority;
11b0: 0a 09 73 63 68 65 64 75 6c 65 72 5f 6c 6f 63 6b ..scheduler_lock
11c0: 28 29 3b 0a 09 71 75 65 75 65 5b 70 72 69 6f 72 ();..queue[prior
11d0: 69 74 79 5d 20 3d 20 74 68 72 65 61 64 5f 71 75 ity] = thread_qu
11e0: 65 75 65 28 71 75 65 75 65 5b 70 72 69 6f 72 69 eue(queue[priori
11f0: 74 79 5d 2c 20 74 68 69 73 2c 20 54 48 52 45 41 ty], this, THREA
1200: 44 5f 52 55 4e 4e 41 42 4c 45 29 3b 0a 09 72 65 D_RUNNABLE);..re
1210: 74 75 72 6e 20 74 68 72 65 61 64 5f 73 63 68 65 turn thread_sche
1220: 64 75 6c 65 28 29 3b 0a 7d 0a 0a 2f 2a 2a 0a 20 dule();.}../**.
1230: 2a 20 4d 61 72 6b 20 67 69 76 65 6e 20 74 68 72 * Mark given thr
1240: 65 61 64 20 61 73 20 69 6e 74 65 72 72 75 70 74 ead as interrupt
1250: 65 64 0a 20 2a 2f 0a 76 6f 69 64 20 74 68 72 65 ed. */.void thre
1260: 61 64 5f 69 6e 74 65 72 72 75 70 74 28 74 68 72 ad_interrupt(thr
1270: 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 29 0a ead_t * thread).
1280: 7b 0a 09 74 68 72 65 61 64 2d 3e 69 6e 74 65 72 {..thread->inter
1290: 72 75 70 74 65 64 20 3d 20 31 3b 0a 7d 0a 0a 2f rupted = 1;.}../
12a0: 2a 2a 0a 20 2a 20 43 68 65 63 6b 20 69 66 20 74 **. * Check if t
12b0: 68 65 20 67 69 76 65 6e 20 74 68 72 65 61 64 20 he given thread
12c0: 68 61 73 20 62 65 65 6e 20 69 6e 74 65 72 72 75 has been interru
12d0: 70 74 65 64 0a 20 2a 20 5c 61 72 67 20 74 68 72 pted. * \arg thr
12e0: 65 61 64 20 54 68 72 65 61 64 20 74 6f 20 63 68 ead Thread to ch
12f0: 65 63 6b 20 66 6f 72 20 69 6e 74 65 72 72 75 70 eck for interrup
1300: 74 69 6f 6e 2e 20 49 66 20 30 2c 20 63 68 65 63 tion. If 0, chec
1310: 6b 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 k current thread
1320: 0a 20 2a 20 5c 72 65 74 75 72 6e 20 74 72 75 65 . * \return true
1330: 20 28 6e 6f 74 20 30 29 20 69 66 20 69 6e 74 65 (not 0) if inte
1340: 72 72 75 70 74 65 64 0a 20 2a 2f 0a 69 6e 74 20 rrupted. */.int
1350: 74 68 72 65 61 64 5f 69 73 69 6e 74 65 72 72 75 thread_isinterru
1360: 70 74 65 64 28 74 68 72 65 61 64 5f 74 20 2a 20 pted(thread_t *
1370: 74 68 72 65 61 64 29 0a 7b 0a 09 69 66 20 28 30 thread).{..if (0
1380: 20 3d 3d 20 74 68 72 65 61 64 29 20 7b 0a 09 09 == thread) {...
1390: 74 68 72 65 61 64 20 3d 20 61 72 63 68 5f 67 65 thread = arch_ge
13a0: 74 5f 74 68 72 65 61 64 28 29 3b 0a 09 7d 0a 0a t_thread();..}..
13b0: 09 72 65 74 75 72 6e 20 74 68 72 65 61 64 2d 3e .return thread->
13c0: 69 6e 74 65 72 72 75 70 74 65 64 3b 0a 7d 0a 0a interrupted;.}..
13d0: 2f 2a 2a 0a 20 2a 20 43 68 65 63 6b 20 69 66 20 /**. * Check if
13e0: 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 the current thre
13f0: 61 64 20 68 61 73 20 62 65 65 6e 20 69 6e 74 65 ad has been inte
1400: 72 72 75 70 74 65 64 2c 20 61 6e 64 20 72 65 73 rrupted, and res
1410: 65 74 20 74 68 65 20 69 6e 74 65 72 72 75 70 74 et the interrupt
1420: 20 66 6c 61 67 0a 20 2a 20 5c 72 65 74 75 72 6e flag. * \return
1430: 20 74 72 75 65 20 28 6e 6f 74 20 30 29 20 69 66 true (not 0) if
1440: 20 69 6e 74 65 72 72 75 70 74 65 64 0a 20 2a 2f interrupted. */
1450: 0a 69 6e 74 20 74 68 72 65 61 64 5f 69 6e 74 65 .int thread_inte
1460: 72 72 75 70 74 65 64 28 29 0a 7b 0a 09 74 68 72 rrupted().{..thr
1470: 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 20 3d ead_t * thread =
1480: 20 61 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 arch_get_thread
1490: 28 29 3b 0a 0a 09 69 66 20 28 74 68 72 65 61 64 ();...if (thread
14a0: 5f 69 73 69 6e 74 65 72 72 75 70 74 65 64 28 74 _isinterrupted(t
14b0: 68 72 65 61 64 29 29 20 7b 0a 09 09 74 68 72 65 hread)) {...thre
14c0: 61 64 2d 3e 69 6e 74 65 72 72 75 70 74 65 64 20 ad->interrupted
14d0: 3d 20 30 3b 0a 09 09 72 65 74 75 72 6e 20 31 3b = 0;...return 1;
14e0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 20 30 3b 0a ..}...return 0;.
14f0: 7d 0a 0a 2f 2a 2a 0a 20 2a 20 52 65 73 75 6d 65 }../**. * Resume
1500: 20 74 68 65 20 67 69 76 65 6e 20 74 68 72 65 61 the given threa
1510: 64 0a 20 2a 20 5c 61 72 67 20 74 68 72 65 61 64 d. * \arg thread
1520: 20 54 68 72 65 61 64 20 74 6f 20 72 65 73 75 6d Thread to resum
1530: 65 0a 20 2a 2f 0a 76 6f 69 64 20 74 68 72 65 61 e. */.void threa
1540: 64 5f 72 65 73 75 6d 65 28 74 68 72 65 61 64 5f d_resume(thread_
1550: 74 20 2a 20 74 68 72 65 61 64 29 0a 7b 0a 09 74 t * thread).{..t
1560: 70 72 69 6f 72 69 74 79 20 70 72 69 6f 72 69 74 priority priorit
1570: 79 20 3d 20 74 68 72 65 61 64 2d 3e 70 72 69 6f y = thread->prio
1580: 72 69 74 79 3b 0a 09 73 63 68 65 64 75 6c 65 72 rity;..scheduler
1590: 5f 6c 6f 63 6b 28 29 3b 0a 09 71 75 65 75 65 5b _lock();..queue[
15a0: 70 72 69 6f 72 69 74 79 5d 20 3d 20 74 68 72 65 priority] = thre
15b0: 61 64 5f 71 75 65 75 65 28 71 75 65 75 65 5b 70 ad_queue(queue[p
15c0: 72 69 6f 72 69 74 79 5d 2c 20 74 68 72 65 61 64 riority], thread
15d0: 2c 20 54 48 52 45 41 44 5f 52 55 4e 4e 41 42 4c , THREAD_RUNNABL
15e0: 45 29 3b 0a 09 73 63 68 65 64 75 6c 65 72 5f 75 E);..scheduler_u
15f0: 6e 6c 6f 63 6b 28 29 3b 0a 09 2f 2a 20 43 68 65 nlock();../* Che
1600: 63 6b 20 66 6f 72 20 70 72 65 2d 65 6d 70 74 69 ck for pre-empti
1610: 6f 6e 20 2a 2f 0a 09 69 66 20 28 61 72 63 68 5f on */..if (arch_
1620: 67 65 74 5f 74 68 72 65 61 64 28 29 2d 3e 70 72 get_thread()->pr
1630: 69 6f 72 69 74 79 20 3e 20 70 72 69 6f 72 69 74 iority > priorit
1640: 79 29 20 7b 0a 09 09 70 72 65 65 6d 70 74 20 3d y) {...preempt =
1650: 20 31 3b 0a 09 7d 0a 7d 0a 0a 2f 2a 2a 0a 20 2a 1;..}.}../**. *
1660: 20 53 63 68 65 64 75 6c 65 20 74 68 65 20 6e 65 Schedule the ne
1670: 78 74 20 74 68 72 65 61 64 0a 20 2a 20 5c 72 65 xt thread. * \re
1680: 74 75 72 6e 20 31 20 69 66 20 61 20 6e 65 77 20 turn 1 if a new
1690: 74 68 72 65 61 64 20 77 61 73 20 73 63 68 65 64 thread was sched
16a0: 75 6c 65 64 0a 20 2a 2f 0a 69 6e 74 20 74 68 72 uled. */.int thr
16b0: 65 61 64 5f 73 63 68 65 64 75 6c 65 28 29 0a 7b ead_schedule().{
16c0: 0a 09 77 68 69 6c 65 28 31 29 20 7b 0a 09 09 69 ..while(1) {...i
16d0: 6e 74 20 69 3b 0a 09 09 66 6f 72 28 69 3d 30 3b nt i;...for(i=0;
16e0: 20 69 3c 54 48 52 45 41 44 5f 50 52 49 4f 52 49 i<THREAD_PRIORI
16f0: 54 49 45 53 3b 20 69 2b 2b 29 20 7b 0a 09 09 09 TIES; i++) {....
1700: 69 66 20 28 71 75 65 75 65 5b 69 5d 29 20 7b 0a if (queue[i]) {.
1710: 09 09 09 09 74 68 72 65 61 64 5f 74 20 2a 20 63 ....thread_t * c
1720: 75 72 72 65 6e 74 20 3d 20 61 72 63 68 5f 67 65 urrent = arch_ge
1730: 74 5f 74 68 72 65 61 64 28 29 3b 0a 09 09 09 09 t_thread();.....
1740: 74 68 72 65 61 64 5f 74 20 2a 20 6e 65 78 74 20 thread_t * next
1750: 3d 20 71 75 65 75 65 5b 69 5d 3b 0a 09 09 09 09 = queue[i];.....
1760: 4c 49 53 54 5f 44 45 4c 45 54 45 28 71 75 65 75 LIST_DELETE(queu
1770: 65 5b 69 5d 2c 20 6e 65 78 74 29 3b 0a 09 09 09 e[i], next);....
1780: 09 73 63 68 65 64 75 6c 65 72 5f 75 6e 6c 6f 63 .scheduler_unloc
1790: 6b 28 29 3b 0a 09 09 09 09 69 66 20 28 61 72 63 k();.....if (arc
17a0: 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 20 21 h_get_thread() !
17b0: 3d 20 6e 65 78 74 29 20 7b 0a 09 09 09 09 09 2f = next) {....../
17c0: 2a 20 54 68 72 65 61 64 20 69 73 20 63 68 61 6e * Thread is chan
17d0: 67 69 6e 67 2c 20 64 6f 20 61 63 63 6f 75 6e 74 ging, do account
17e0: 69 6e 67 20 61 6e 64 20 73 77 69 74 63 68 20 74 ing and switch t
17f0: 6f 20 6e 65 78 74 20 2a 2f 0a 09 09 09 09 09 63 o next */......c
1800: 75 72 72 65 6e 74 2d 3e 61 63 63 74 73 5b 63 75 urrent->accts[cu
1810: 72 72 65 6e 74 2d 3e 61 63 63 74 5d 2e 74 6c 65 rrent->acct].tle
1820: 6e 20 3d 20 74 69 6d 65 72 5f 75 70 74 69 6d 65 n = timer_uptime
1830: 28 31 29 20 2d 20 63 75 72 72 65 6e 74 2d 3e 61 (1) - current->a
1840: 63 63 74 73 5b 63 75 72 72 65 6e 74 2d 3e 61 63 ccts[current->ac
1850: 63 74 5d 2e 74 73 74 61 72 74 3b 0a 09 09 09 09 ct].tstart;.....
1860: 09 63 75 72 72 65 6e 74 2d 3e 61 63 63 74 2b 2b .current->acct++
1870: 3b 0a 09 09 09 09 09 69 66 20 28 73 69 7a 65 6f ;......if (sizeo
1880: 66 28 63 75 72 72 65 6e 74 2d 3e 61 63 63 74 73 f(current->accts
1890: 29 2f 73 69 7a 65 6f 66 28 63 75 72 72 65 6e 74 )/sizeof(current
18a0: 2d 3e 61 63 63 74 73 5b 30 5d 29 20 3d 3d 20 63 ->accts[0]) == c
18b0: 75 72 72 65 6e 74 2d 3e 61 63 63 74 29 20 7b 0a urrent->acct) {.
18c0: 09 09 09 09 09 09 63 75 72 72 65 6e 74 2d 3e 61 ......current->a
18d0: 63 63 74 20 3d 20 30 3b 0a 09 09 09 09 09 7d 0a cct = 0;......}.
18e0: 09 09 09 09 09 61 72 63 68 5f 74 68 72 65 61 64 .....arch_thread
18f0: 5f 73 77 69 74 63 68 28 6e 65 78 74 29 3b 0a 09 _switch(next);..
1900: 09 09 09 09 63 75 72 72 65 6e 74 2d 3e 61 63 63 ....current->acc
1910: 74 73 5b 63 75 72 72 65 6e 74 2d 3e 61 63 63 74 ts[current->acct
1920: 5d 2e 74 73 74 61 72 74 20 3d 20 74 69 6d 65 72 ].tstart = timer
1930: 5f 75 70 74 69 6d 65 28 31 29 3b 0a 09 09 09 09 _uptime(1);.....
1940: 09 2f 2a 20 42 79 20 64 65 66 61 75 6c 74 2c 20 ./* By default,
1950: 70 72 65 65 6d 70 74 20 61 66 74 65 72 20 31 30 preempt after 10
1960: 30 6d 73 20 2a 2f 0a 09 09 09 09 09 63 75 72 72 0ms */......curr
1970: 65 6e 74 2d 3e 70 72 65 65 6d 70 74 20 3d 20 63 ent->preempt = c
1980: 75 72 72 65 6e 74 2d 3e 61 63 63 74 73 5b 63 75 urrent->accts[cu
1990: 72 72 65 6e 74 2d 3e 61 63 63 74 5d 2e 74 73 74 rrent->acct].tst
19a0: 61 72 74 20 2b 20 31 30 30 30 30 30 3b 0a 09 09 art + 100000;...
19b0: 09 09 09 72 65 74 75 72 6e 20 31 3b 0a 09 09 09 ...return 1;....
19c0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 2f .} else {....../
19d0: 2a 20 52 65 73 74 6f 72 65 20 74 68 72 65 61 64 * Restore thread
19e0: 20 73 74 61 74 65 20 74 6f 20 72 75 6e 6e 69 6e state to runnin
19f0: 67 20 2a 2f 0a 09 09 09 09 09 63 75 72 72 65 6e g */......curren
1a00: 74 2d 3e 73 74 61 74 65 20 3d 20 54 48 52 45 41 t->state = THREA
1a10: 44 5f 52 55 4e 4e 49 4e 47 3b 0a 09 09 09 09 09 D_RUNNING;......
1a20: 72 65 74 75 72 6e 20 30 3b 0a 09 09 09 09 7d 0a return 0;.....}.
1a30: 09 09 09 7d 0a 09 09 7d 0a 09 09 2f 2f 20 6b 65 ...}...}...// ke
1a40: 72 6e 65 6c 5f 70 72 69 6e 74 6b 28 22 45 6d 70 rnel_printk("Emp
1a50: 74 79 20 72 75 6e 20 71 75 65 75 65 21 5c 6e 22 ty run queue!\n"
1a60: 29 3b 0a 09 09 73 63 68 65 64 75 6c 65 72 5f 75 );...scheduler_u
1a70: 6e 6c 6f 63 6b 28 29 3b 0a 09 09 61 72 63 68 5f nlock();...arch_
1a80: 69 64 6c 65 28 29 3b 0a 09 09 73 63 68 65 64 75 idle();...schedu
1a90: 6c 65 72 5f 6c 6f 63 6b 28 29 3b 0a 09 7d 0a 7d ler_lock();..}.}
1aa0: 0a 0a 2f 2a 2a 0a 20 2a 20 47 65 74 20 74 68 65 ../**. * Get the
1ab0: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 67 69 76 name of the giv
1ac0: 65 6e 20 74 68 72 65 61 64 0a 20 2a 20 5c 61 72 en thread. * \ar
1ad0: 67 20 74 68 72 65 61 64 20 54 68 72 65 61 64 2c g thread Thread,
1ae0: 20 6f 72 20 63 75 72 72 65 6e 74 20 74 68 72 65 or current thre
1af0: 61 64 20 69 66 20 30 0a 20 2a 20 5c 72 65 74 75 ad if 0. * \retu
1b00: 72 6e 20 54 68 72 65 61 64 20 6e 61 6d 65 2c 20 rn Thread name,
1b10: 69 66 20 73 65 74 0a 20 2a 2f 0a 63 68 61 72 20 if set. */.char
1b20: 2a 20 74 68 72 65 61 64 5f 67 65 74 5f 6e 61 6d * thread_get_nam
1b30: 65 28 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 e(thread_t * thr
1b40: 65 61 64 29 0a 7b 0a 09 69 66 20 28 30 20 3d 3d ead).{..if (0 ==
1b50: 20 74 68 72 65 61 64 29 20 7b 0a 09 09 74 68 72 thread) {...thr
1b60: 65 61 64 20 3d 20 61 72 63 68 5f 67 65 74 5f 74 ead = arch_get_t
1b70: 68 72 65 61 64 28 29 3b 0a 09 7d 0a 0a 09 69 66 hread();..}...if
1b80: 20 28 30 20 3d 3d 20 74 68 72 65 61 64 2d 3e 6e (0 == thread->n
1b90: 61 6d 65 29 20 7b 0a 09 09 74 68 72 65 61 64 2d ame) {...thread-
1ba0: 3e 6e 61 6d 65 20 3d 20 22 41 6e 6f 6e 79 6d 6f >name = "Anonymo
1bb0: 75 73 22 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e us";..}...return
1bc0: 20 74 68 72 65 61 64 2d 3e 6e 61 6d 65 3b 0a 7d thread->name;.}
1bd0: 0a 0a 2f 2a 2a 0a 20 2a 20 53 65 74 20 74 68 65 ../**. * Set the
1be0: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 67 69 76 name of the giv
1bf0: 65 6e 20 74 68 72 65 61 64 0a 20 2a 20 5c 61 72 en thread. * \ar
1c00: 67 20 74 68 72 65 61 64 20 54 68 72 65 61 64 2c g thread Thread,
1c10: 20 6f 72 20 63 75 72 72 65 6e 74 20 74 68 72 65 or current thre
1c20: 61 64 20 69 66 20 30 0a 20 2a 20 5c 61 72 67 20 ad if 0. * \arg
1c30: 6e 61 6d 65 20 4e 65 77 20 74 68 72 65 61 64 20 name New thread
1c40: 6e 61 6d 65 0a 20 2a 2f 0a 76 6f 69 64 20 74 68 name. */.void th
1c50: 72 65 61 64 5f 73 65 74 5f 6e 61 6d 65 28 74 68 read_set_name(th
1c60: 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 2c read_t * thread,
1c70: 20 63 68 61 72 20 2a 20 6e 61 6d 65 29 0a 7b 0a char * name).{.
1c80: 09 69 66 20 28 30 20 3d 3d 20 74 68 72 65 61 64 .if (0 == thread
1c90: 29 20 7b 0a 09 09 74 68 72 65 61 64 20 3d 20 61 ) {...thread = a
1ca0: 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 rch_get_thread()
1cb0: 3b 0a 09 7d 0a 0a 09 74 68 72 65 61 64 2d 3e 6e ;..}...thread->n
1cc0: 61 6d 65 20 3d 20 6e 61 6d 65 3b 0a 7d 0a 0a 73 ame = name;.}..s
1cd0: 74 61 74 69 63 20 73 70 69 6e 5f 74 20 61 6c 6c tatic spin_t all
1ce0: 74 68 72 65 61 64 73 6c 6f 63 6b 20 3d 20 41 54 threadslock = AT
1cf0: 4f 4d 49 43 5f 46 4c 41 47 5f 49 4e 49 54 3b 0a OMIC_FLAG_INIT;.
1d00: 73 74 61 74 69 63 20 47 43 52 4f 4f 54 20 6d 61 static GCROOT ma
1d10: 70 5f 74 20 2a 20 61 6c 6c 74 68 72 65 61 64 73 p_t * allthreads
1d20: 20 3d 20 30 3b 0a 73 74 61 74 69 63 20 76 6f 69 = 0;.static voi
1d30: 64 20 74 68 72 65 61 64 5f 74 72 61 63 6b 28 74 d thread_track(t
1d40: 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 hread_t * thread
1d50: 2c 20 69 6e 74 20 61 64 64 29 0a 7b 0a 09 53 50 , int add).{..SP
1d60: 49 4e 5f 41 55 54 4f 4c 4f 43 4b 28 26 61 6c 6c IN_AUTOLOCK(&all
1d70: 74 68 72 65 61 64 73 6c 6f 63 6b 29 20 7b 0a 09 threadslock) {..
1d80: 09 69 66 20 28 30 20 3d 3d 20 61 6c 6c 74 68 72 .if (0 == allthr
1d90: 65 61 64 73 29 20 7b 0a 09 09 09 2f 2a 20 41 6c eads) {..../* Al
1da0: 6c 20 74 68 72 65 61 64 73 20 2a 2f 0a 09 09 09 l threads */....
1db0: 61 6c 6c 74 68 72 65 61 64 73 20 3d 20 74 72 65 allthreads = tre
1dc0: 65 5f 6e 65 77 28 30 2c 20 54 52 45 45 5f 54 52 e_new(0, TREE_TR
1dd0: 45 41 50 29 3b 0a 09 09 7d 0a 09 09 69 66 20 28 EAP);...}...if (
1de0: 61 64 64 29 20 7b 0a 09 09 09 69 66 20 28 6d 61 add) {....if (ma
1df0: 70 5f 70 75 74 70 70 28 61 6c 6c 74 68 72 65 61 p_putpp(allthrea
1e00: 64 73 2c 20 74 68 72 65 61 64 2c 20 74 68 72 65 ds, thread, thre
1e10: 61 64 29 29 20 7b 0a 09 09 09 09 6b 65 72 6e 65 ad)) {.....kerne
1e20: 6c 5f 70 61 6e 69 63 28 22 41 64 64 69 6e 67 20 l_panic("Adding
1e30: 65 78 69 73 74 69 6e 67 20 74 68 72 65 61 64 21 existing thread!
1e40: 22 29 3b 0a 09 09 09 7d 0a 09 09 7d 20 65 6c 73 ");....}...} els
1e50: 65 20 7b 0a 09 09 09 69 66 20 28 30 20 3d 3d 20 e {....if (0 ==
1e60: 6d 61 70 5f 72 65 6d 6f 76 65 70 70 28 61 6c 6c map_removepp(all
1e70: 74 68 72 65 61 64 73 2c 20 74 68 72 65 61 64 29 threads, thread)
1e80: 29 20 7b 0a 09 09 09 09 6b 65 72 6e 65 6c 5f 70 ) {.....kernel_p
1e90: 61 6e 69 63 28 22 52 65 6d 6f 76 69 6e 67 20 6e anic("Removing n
1ea0: 6f 6e 2d 65 78 69 73 74 65 6e 74 20 74 68 72 65 on-existent thre
1eb0: 61 64 21 22 29 3b 0a 09 09 09 7d 0a 09 09 7d 0a ad!");....}...}.
1ec0: 09 7d 0a 7d 0a 0a 2f 2a 2a 0a 20 2a 20 53 70 61 .}.}../**. * Spa
1ed0: 77 6e 20 61 20 6e 65 77 20 74 68 72 65 61 64 0a wn a new thread.
1ee0: 20 2a 20 5c 61 72 67 20 66 20 46 75 6e 63 74 69 * \arg f Functi
1ef0: 6f 6e 20 69 6e 74 6f 20 77 68 69 63 68 20 74 68 on into which th
1f00: 65 20 6e 65 77 20 74 68 72 65 61 64 20 77 69 6c e new thread wil
1f10: 6c 20 72 75 6e 0a 20 2a 20 5c 61 72 67 20 61 72 l run. * \arg ar
1f20: 67 20 41 72 67 75 6d 65 6e 74 20 74 6f 20 6e 65 g Argument to ne
1f30: 77 20 74 68 72 65 61 64 0a 20 2a 20 5c 72 65 74 w thread. * \ret
1f40: 75 72 6e 20 74 68 72 65 61 64 20 70 6f 69 6e 74 urn thread point
1f50: 65 72 20 74 6f 20 74 68 65 20 6e 65 77 20 74 68 er to the new th
1f60: 72 65 61 64 0a 20 2a 2f 0a 74 68 72 65 61 64 5f read. */.thread_
1f70: 74 20 2a 20 74 68 72 65 61 64 5f 73 70 61 77 6e t * thread_spawn
1f80: 28 74 68 72 65 61 64 5f 66 75 6e 63 5f 74 20 66 (thread_func_t f
1f90: 2c 20 76 6f 69 64 20 2a 20 61 72 67 29 0a 7b 0a , void * arg).{.
1fa0: 09 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 .thread_t * thre
1fb0: 61 64 20 3d 20 74 68 72 65 61 64 5f 66 6f 72 6b ad = thread_fork
1fc0: 28 29 3b 0a 09 69 66 20 28 74 68 72 65 61 64 29 ();..if (thread)
1fd0: 20 7b 0a 09 09 72 65 74 75 72 6e 20 74 68 72 65 {...return thre
1fe0: 61 64 3b 0a 09 7d 0a 09 2f 2a 20 43 68 69 6c 64 ad;..}../* Child
1ff0: 20 74 68 72 65 61 64 20 2a 2f 0a 09 76 6f 69 64 thread */..void
2000: 20 2a 20 72 65 74 76 61 6c 20 3d 20 66 28 61 72 * retval = f(ar
2010: 67 29 3b 0a 09 74 68 72 65 61 64 5f 65 78 69 74 g);..thread_exit
2020: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 2a (retval);.}../**
2030: 0a 20 2a 20 46 6f 72 6b 20 74 68 65 20 63 75 72 . * Fork the cur
2040: 72 65 6e 74 20 74 68 72 65 61 64 2c 20 69 6e 74 rent thread, int
2050: 6f 20 61 20 6e 65 77 20 74 68 72 65 61 64 0a 20 o a new thread.
2060: 2a 0a 20 2a 20 46 6f 72 6b 20 74 68 65 20 63 75 *. * Fork the cu
2070: 72 72 65 6e 74 20 74 68 72 65 61 64 2c 20 72 65 rrent thread, re
2080: 74 75 72 6e 69 6e 67 20 74 68 65 20 6e 65 77 20 turning the new
2090: 74 68 72 65 61 64 20 70 6f 69 6e 74 65 72 20 74 thread pointer t
20a0: 6f 20 74 68 65 0a 20 2a 20 63 72 65 61 74 6f 72 o the. * creator
20b0: 20 74 68 72 65 61 64 2c 20 61 6e 64 20 30 20 74 thread, and 0 t
20c0: 6f 20 74 68 65 20 63 72 65 61 74 65 64 20 74 68 o the created th
20d0: 72 65 61 64 2e 0a 20 2a 0a 20 2a 20 54 68 65 20 read.. *. * The
20e0: 63 72 65 61 74 65 64 20 74 68 72 65 61 64 20 69 created thread i
20f0: 73 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 s a copy of the
2100: 63 72 65 61 74 6f 72 20 74 68 72 65 61 64 2c 20 creator thread,
2110: 77 69 74 68 20 74 68 65 20 73 61 6d 65 20 63 61 with the same ca
2120: 6c 6c 20 63 68 61 69 6e 2e 0a 20 2a 0a 20 2a 20 ll chain.. *. *
2130: 41 75 74 6f 6d 61 74 69 63 20 76 61 72 69 61 62 Automatic variab
2140: 6c 65 73 20 74 68 61 74 20 63 6f 6e 74 61 69 6e les that contain
2150: 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 6c 6f 63 pointers to loc
2160: 61 74 69 6f 6e 73 20 69 6e 20 74 68 65 20 63 72 ations in the cr
2170: 65 61 74 6f 72 20 73 74 61 63 6b 20 61 72 65 0a eator stack are.
2180: 20 2a 20 74 72 61 6e 73 66 6f 72 6d 65 64 20 74 * transformed t
2190: 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 65 o point to the e
21a0: 71 75 69 76 61 6c 65 6e 74 20 6c 6f 63 61 74 69 quivalent locati
21b0: 6f 6e 73 20 69 6e 20 74 68 65 20 63 72 65 61 74 ons in the creat
21c0: 65 64 20 73 74 61 63 6b 2e 0a 20 2a 20 5c 72 65 ed stack.. * \re
21d0: 74 75 72 6e 20 74 68 72 65 61 64 20 70 6f 69 6e turn thread poin
21e0: 74 65 72 20 74 6f 20 74 68 65 20 6e 65 77 20 74 ter to the new t
21f0: 68 72 65 61 64 20 69 6e 20 74 68 65 20 63 72 65 hread in the cre
2200: 61 74 6f 72 2c 20 6f 72 20 30 20 69 6e 20 74 68 ator, or 0 in th
2210: 65 20 6e 65 77 20 74 68 72 65 61 64 0a 20 2a 2f e new thread. */
2220: 0a 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 .thread_t * thre
2230: 61 64 5f 66 6f 72 6b 28 29 0a 7b 0a 09 74 68 72 ad_fork().{..thr
2240: 65 61 64 5f 74 20 2a 20 74 68 69 73 20 3d 20 61 ead_t * this = a
2250: 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 rch_get_thread()
2260: 3b 0a 09 74 68 72 65 61 64 5f 74 20 2a 20 74 68 ;..thread_t * th
2270: 72 65 61 64 20 3d 20 73 6c 61 62 5f 63 61 6c 6c read = slab_call
2280: 6f 63 28 74 68 72 65 61 64 73 29 3b 0a 0a 09 74 oc(threads);...t
2290: 68 72 65 61 64 2d 3e 70 72 69 6f 72 69 74 79 20 hread->priority
22a0: 3d 20 74 68 69 73 2d 3e 70 72 69 6f 72 69 74 79 = this->priority
22b0: 3b 0a 09 74 68 72 65 61 64 2d 3e 70 72 6f 63 65 ;..thread->proce
22c0: 73 73 20 3d 20 74 68 69 73 2d 3e 70 72 6f 63 65 ss = this->proce
22d0: 73 73 3b 0a 09 63 68 61 72 20 62 75 66 5b 33 32 ss;..char buf[32
22e0: 5d 3b 0a 09 73 6e 70 72 69 6e 74 66 28 20 62 75 ];..snprintf( bu
22f0: 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20 f, sizeof(buf),
2300: 22 43 68 69 6c 64 20 6f 66 20 25 70 22 2c 20 74 "Child of %p", t
2310: 68 69 73 29 3b 0a 09 74 68 72 65 61 64 5f 73 65 his);..thread_se
2320: 74 5f 6e 61 6d 65 28 74 68 72 65 61 64 2c 20 73 t_name(thread, s
2330: 74 72 6e 64 75 70 28 62 75 66 2c 20 73 69 7a 65 trndup(buf, size
2340: 6f 66 28 62 75 66 29 29 29 3b 0a 0a 09 69 66 20 of(buf)));...if
2350: 28 30 20 3d 3d 20 61 72 63 68 5f 74 68 72 65 61 (0 == arch_threa
2360: 64 5f 66 6f 72 6b 28 74 68 72 65 61 64 29 29 20 d_fork(thread))
2370: 7b 0a 09 09 72 65 74 75 72 6e 20 30 3b 0a 09 7d {...return 0;..}
2380: 0a 0a 09 74 68 72 65 61 64 5f 74 72 61 63 6b 28 ...thread_track(
2390: 74 68 72 65 61 64 2c 20 31 29 3b 0a 09 74 68 72 thread, 1);..thr
23a0: 65 61 64 5f 72 65 73 75 6d 65 28 74 68 72 65 61 ead_resume(threa
23b0: 64 29 3b 0a 0a 09 72 65 74 75 72 6e 20 74 68 72 d);...return thr
23c0: 65 61 64 3b 0a 7d 0a 0a 2f 2a 2a 0a 20 2a 20 45 ead;.}../**. * E
23d0: 78 69 74 20 74 68 65 20 63 75 72 72 65 6e 74 20 xit the current
23e0: 74 68 72 65 61 64 2e 0a 20 2a 0a 20 2a 20 45 78 thread.. *. * Ex
23f0: 69 74 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 it the current t
2400: 68 72 65 61 64 2e 20 54 68 69 73 20 66 75 6e 63 hread. This func
2410: 74 69 6f 6e 20 6e 65 76 65 72 20 72 65 74 75 72 tion never retur
2420: 6e 73 2e 0a 20 2a 20 5c 61 72 67 20 72 65 74 76 ns.. * \arg retv
2430: 61 6c 20 52 65 74 75 72 6e 20 76 61 6c 75 65 20 al Return value
2440: 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20 returned to the
2450: 63 61 6c 6c 65 72 20 6f 66 20 5c 72 65 66 20 74 caller of \ref t
2460: 68 72 65 61 64 5f 6a 6f 69 6e 2e 0a 20 2a 2f 0a hread_join.. */.
2470: 6e 6f 72 65 74 75 72 6e 20 76 6f 69 64 20 74 68 noreturn void th
2480: 72 65 61 64 5f 65 78 69 74 28 76 6f 69 64 20 2a read_exit(void *
2490: 20 72 65 74 76 61 6c 29 0a 7b 0a 09 74 68 72 65 retval).{..thre
24a0: 61 64 5f 74 20 2a 20 74 68 69 73 20 3d 20 61 72 ad_t * this = ar
24b0: 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 3b ch_get_thread();
24c0: 0a 0a 09 74 68 69 73 2d 3e 72 65 74 76 61 6c 20 ...this->retval
24d0: 3d 20 72 65 74 76 61 6c 3b 0a 09 74 68 69 73 2d = retval;..this-
24e0: 3e 73 74 61 74 65 20 3d 20 54 48 52 45 41 44 5f >state = THREAD_
24f0: 54 45 52 4d 49 4e 41 54 45 44 3b 0a 0a 09 2f 2a TERMINATED;.../*
2500: 20 53 69 67 6e 69 66 79 20 74 6f 20 61 6e 79 20 Signify to any
2510: 74 68 72 65 61 64 73 20 77 61 69 74 69 6e 67 20 threads waiting
2520: 6f 6e 20 74 68 69 73 20 74 68 72 65 61 64 20 2a on this thread *
2530: 2f 0a 09 4d 4f 4e 49 54 4f 52 5f 41 55 54 4f 4c /..MONITOR_AUTOL
2540: 4f 43 4b 28 74 68 69 73 2d 3e 6c 6f 63 6b 29 20 OCK(this->lock)
2550: 7b 0a 09 09 6d 6f 6e 69 74 6f 72 5f 62 72 6f 61 {...monitor_broa
2560: 64 63 61 73 74 28 74 68 69 73 2d 3e 6c 6f 63 6b dcast(this->lock
2570: 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 6d 6f 76 );..}.../* Remov
2580: 65 20 74 68 69 73 20 74 68 72 65 61 64 20 66 72 e this thread fr
2590: 6f 6d 20 74 68 65 20 73 65 74 20 6f 66 20 70 72 om the set of pr
25a0: 6f 63 65 73 73 20 74 68 72 65 61 64 73 20 2a 2f ocess threads */
25b0: 0a 09 69 66 20 28 74 68 69 73 2d 3e 70 72 6f 63 ..if (this->proc
25c0: 65 73 73 29 20 7b 0a 09 09 4d 4f 4e 49 54 4f 52 ess) {...MONITOR
25d0: 5f 41 55 54 4f 4c 4f 43 4b 28 26 74 68 69 73 2d _AUTOLOCK(&this-
25e0: 3e 70 72 6f 63 65 73 73 2d 3e 6c 6f 63 6b 29 20 >process->lock)
25f0: 7b 0a 09 09 09 6d 61 70 5f 72 65 6d 6f 76 65 70 {....map_removep
2600: 70 28 74 68 69 73 2d 3e 70 72 6f 63 65 73 73 2d p(this->process-
2610: 3e 74 68 72 65 61 64 73 2c 20 74 68 69 73 29 3b >threads, this);
2620: 0a 09 09 7d 0a 09 7d 0a 0a 09 74 68 69 73 2d 3e ...}..}...this->
2630: 70 72 6f 63 65 73 73 20 3d 20 30 3b 0a 0a 09 2f process = 0;.../
2640: 2a 20 52 65 6d 6f 76 65 20 74 68 69 73 20 74 68 * Remove this th
2650: 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 73 65 read from the se
2660: 74 20 6f 66 20 61 6c 6c 20 74 68 72 65 61 64 73 t of all threads
2670: 20 2a 2f 0a 09 74 68 72 65 61 64 5f 74 72 61 63 */..thread_trac
2680: 6b 28 74 68 69 73 2c 20 30 29 3b 0a 0a 09 2f 2a k(this, 0);.../*
2690: 20 53 63 68 65 64 75 6c 65 20 74 68 65 20 6e 65 Schedule the ne
26a0: 78 74 20 74 68 72 65 61 64 20 2a 2f 0a 09 73 63 xt thread */..sc
26b0: 68 65 64 75 6c 65 72 5f 6c 6f 63 6b 28 29 3b 0a heduler_lock();.
26c0: 09 74 68 72 65 61 64 5f 73 63 68 65 64 75 6c 65 .thread_schedule
26d0: 28 29 3b 0a 09 6b 65 72 6e 65 6c 5f 70 61 6e 69 ();..kernel_pani
26e0: 63 28 22 74 68 72 65 61 64 5f 65 78 69 74 3a 20 c("thread_exit:
26f0: 53 68 6f 75 6c 64 20 6e 65 76 65 72 20 67 65 74 Should never get
2700: 20 68 65 72 65 5c 6e 22 29 3b 0a 7d 0a 0a 2f 2a here\n");.}../*
2710: 2a 0a 20 2a 20 47 65 74 20 72 65 74 75 72 6e 20 *. * Get return
2720: 63 6f 64 65 20 66 72 6f 6d 20 67 69 76 65 6e 20 code from given
2730: 74 68 72 65 61 64 2e 0a 20 2a 0a 20 2a 20 47 65 thread.. *. * Ge
2740: 74 20 72 65 74 75 72 6e 20 63 6f 64 65 20 66 72 t return code fr
2750: 6f 6d 20 67 69 76 65 6e 20 74 68 72 65 61 64 2e om given thread.
2760: 20 49 66 20 74 68 65 20 74 68 72 65 61 64 20 68 If the thread h
2770: 61 73 20 6e 6f 74 20 79 65 74 20 65 78 69 74 65 as not yet exite
2780: 64 2c 0a 20 2a 20 74 68 65 20 63 75 72 72 65 6e d,. * the curren
2790: 74 20 74 68 72 65 61 64 20 77 69 6c 6c 20 73 6c t thread will sl
27a0: 65 65 70 20 77 61 69 74 69 6e 67 20 66 6f 72 20 eep waiting for
27b0: 74 68 65 20 74 68 72 65 61 64 20 74 6f 20 65 78 the thread to ex
27c0: 69 74 2e 0a 20 2a 0a 20 2a 20 5c 61 72 67 20 74 it.. *. * \arg t
27d0: 68 72 65 61 64 20 54 68 72 65 61 64 20 74 6f 20 hread Thread to
27e0: 67 65 74 20 72 65 74 75 72 6e 20 63 6f 64 65 20 get return code
27f0: 66 72 6f 6d 2e 0a 20 2a 20 5c 72 65 74 75 72 6e from.. * \return
2800: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 61 73 20 Return code as
2810: 70 61 73 73 65 64 20 74 6f 20 5c 72 65 66 20 74 passed to \ref t
2820: 68 72 65 61 64 5f 65 78 69 74 0a 20 2a 2f 0a 76 hread_exit. */.v
2830: 6f 69 64 20 2a 20 74 68 72 65 61 64 5f 6a 6f 69 oid * thread_joi
2840: 6e 28 74 68 72 65 61 64 5f 74 20 2a 20 74 68 72 n(thread_t * thr
2850: 65 61 64 29 0a 7b 0a 09 4d 4f 4e 49 54 4f 52 5f ead).{..MONITOR_
2860: 41 55 54 4f 4c 4f 43 4b 28 74 68 72 65 61 64 2d AUTOLOCK(thread-
2870: 3e 6c 6f 63 6b 29 20 7b 0a 09 09 77 68 69 6c 65 >lock) {...while
2880: 28 74 68 72 65 61 64 2d 3e 73 74 61 74 65 20 21 (thread->state !
2890: 3d 20 54 48 52 45 41 44 5f 54 45 52 4d 49 4e 41 = THREAD_TERMINA
28a0: 54 45 44 29 20 7b 0a 09 09 09 6d 6f 6e 69 74 6f TED) {....monito
28b0: 72 5f 77 61 69 74 28 74 68 72 65 61 64 2d 3e 6c r_wait(thread->l
28c0: 6f 63 6b 29 3b 0a 09 09 7d 0a 09 7d 0a 09 72 65 ock);...}..}..re
28d0: 74 75 72 6e 20 74 68 72 65 61 64 2d 3e 72 65 74 turn thread->ret
28e0: 76 61 6c 3b 0a 7d 0a 0a 2f 2a 2a 0a 20 2a 20 53 val;.}../**. * S
28f0: 65 74 20 74 68 65 20 70 72 69 6f 72 69 74 79 20 et the priority
2900: 6f 66 20 74 68 65 20 67 69 76 65 6e 20 74 68 72 of the given thr
2910: 65 61 64 2e 0a 20 2a 20 5c 61 72 67 20 74 68 72 ead.. * \arg thr
2920: 65 61 64 20 54 68 72 65 61 64 20 74 6f 20 73 65 ead Thread to se
2930: 74 20 70 72 69 6f 72 69 74 79 20 6f 66 2c 20 6f t priority of, o
2940: 72 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 r current thread
2950: 20 69 66 20 30 2e 0a 20 2a 20 5c 61 72 67 20 70 if 0.. * \arg p
2960: 72 69 6f 72 69 74 79 20 4e 65 77 20 74 68 72 65 riority New thre
2970: 61 64 20 70 72 69 6f 72 69 74 79 2e 0a 20 2a 2f ad priority.. */
2980: 0a 76 6f 69 64 20 74 68 72 65 61 64 5f 73 65 74 .void thread_set
2990: 5f 70 72 69 6f 72 69 74 79 28 74 68 72 65 61 64 _priority(thread
29a0: 5f 74 20 2a 20 74 68 72 65 61 64 2c 20 74 70 72 _t * thread, tpr
29b0: 69 6f 72 69 74 79 20 70 72 69 6f 72 69 74 79 29 iority priority)
29c0: 0a 7b 0a 09 63 68 65 63 6b 5f 69 6e 74 5f 62 6f .{..check_int_bo
29d0: 75 6e 64 73 28 70 72 69 6f 72 69 74 79 2c 20 54 unds(priority, T
29e0: 48 52 45 41 44 5f 49 4e 54 45 52 52 55 50 54 2c HREAD_INTERRUPT,
29f0: 20 54 48 52 45 41 44 5f 49 44 4c 45 2c 20 22 54 THREAD_IDLE, "T
2a00: 68 72 65 61 64 20 70 72 69 6f 72 69 74 79 20 6f hread priority o
2a10: 75 74 20 6f 66 20 62 6f 75 6e 64 73 22 29 3b 0a ut of bounds");.
2a20: 09 69 66 20 28 30 20 3d 3d 20 74 68 72 65 61 64 .if (0 == thread
2a30: 29 20 7b 0a 09 09 74 68 72 65 61 64 20 3d 20 61 ) {...thread = a
2a40: 72 63 68 5f 67 65 74 5f 74 68 72 65 61 64 28 29 rch_get_thread()
2a50: 3b 0a 09 7d 0a 09 74 68 72 65 61 64 2d 3e 70 72 ;..}..thread->pr
2a60: 69 6f 72 69 74 79 20 3d 20 70 72 69 6f 72 69 74 iority = priorit
2a70: 79 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 47 43 52 y;.}..static GCR
2a80: 4f 4f 54 20 76 6f 69 64 20 2a 2a 20 72 6f 6f 74 OOT void ** root
2a90: 73 3b 0a 0a 23 64 65 66 69 6e 65 20 47 43 50 52 s;..#define GCPR
2aa0: 4f 46 49 4c 45 20 31 0a 0a 23 69 66 20 47 43 50 OFILE 1..#if GCP
2ab0: 52 4f 46 49 4c 45 0a 73 74 61 74 69 63 20 74 69 ROFILE.static ti
2ac0: 6d 65 72 73 70 65 63 5f 74 20 67 63 74 69 6d 65 merspec_t gctime
2ad0: 20 3d 20 30 3b 0a 23 65 6e 64 69 66 0a 0a 2f 2a = 0;.#endif../*
2ae0: 2a 0a 20 2a 20 52 75 6e 20 67 61 72 62 61 67 65 *. * Run garbage
2af0: 20 63 6f 6c 6c 65 63 74 69 6f 6e 2e 0a 20 2a 2f collection.. */
2b00: 0a 76 6f 69 64 20 74 68 72 65 61 64 5f 67 63 28 .void thread_gc(
2b10: 29 0a 7b 0a 09 2f 2f 20 74 68 72 65 61 64 5f 63 ).{..// thread_c
2b20: 6c 65 61 6e 6c 6f 63 6b 73 28 29 3b 0a 23 69 66 leanlocks();.#if
2b30: 20 47 43 50 52 4f 46 49 4c 45 0a 09 74 69 6d 65 GCPROFILE..time
2b40: 72 73 70 65 63 5f 74 20 73 74 61 72 74 20 3d 20 rspec_t start =
2b50: 74 69 6d 65 72 5f 75 70 74 69 6d 65 28 31 29 3b timer_uptime(1);
2b60: 0a 23 65 6e 64 69 66 0a 09 73 6c 61 62 5f 67 63 .#endif..slab_gc
2b70: 5f 62 65 67 69 6e 28 29 3b 0a 09 73 6c 61 62 5f _begin();..slab_
2b80: 67 63 28 29 3b 0a 09 73 6c 61 62 5f 67 63 5f 65 gc();..slab_gc_e
2b90: 6e 64 28 29 3b 0a 23 69 66 20 47 43 50 52 4f 46 nd();.#if GCPROF
2ba0: 49 4c 45 0a 09 73 74 61 74 69 63 20 74 69 6d 65 ILE..static time
2bb0: 72 73 70 65 63 5f 74 20 67 63 74 69 6d 65 20 3d rspec_t gctime =
2bc0: 20 30 3b 0a 09 67 63 74 69 6d 65 20 2b 3d 20 28 0;..gctime += (
2bd0: 74 69 6d 65 72 5f 75 70 74 69 6d 65 28 31 29 20 timer_uptime(1)
2be0: 2d 20 73 74 61 72 74 29 3b 0a 09 6b 65 72 6e 65 - start);..kerne
2bf0: 6c 5f 70 72 69 6e 74 6b 28 22 47 43 20 74 69 6d l_printk("GC tim
2c00: 65 20 25 64 20 28 25 64 25 25 29 5c 6e 22 2c 20 e %d (%d%%)\n",
2c10: 28 69 6e 74 29 67 63 74 69 6d 65 2c 20 28 69 6e (int)gctime, (in
2c20: 74 29 28 31 30 30 30 20 2a 20 67 63 74 69 6d 65 t)(1000 * gctime
2c30: 20 2f 20 73 74 61 72 74 29 29 3b 0a 23 65 6e 64 / start));.#end
2c40: 69 66 0a 7d 0a 0a 2f 2a 2a 0a 20 2a 20 41 64 64 if.}../**. * Add
2c50: 20 61 20 6e 65 77 20 67 61 72 62 61 67 65 20 63 a new garbage c
2c60: 6f 6c 6c 65 63 74 69 6f 6e 20 72 6f 6f 74 2e 0a ollection root..
2c70: 20 2a 20 5c 61 72 67 20 70 20 50 6f 69 6e 74 65 * \arg p Pointe
2c80: 72 20 74 6f 20 74 68 65 20 6e 65 77 20 72 6f 6f r to the new roo
2c90: 74 2e 0a 20 2a 2f 0a 76 6f 69 64 20 74 68 72 65 t.. */.void thre
2ca0: 61 64 5f 67 63 5f 72 6f 6f 74 28 76 6f 69 64 20 ad_gc_root(void
2cb0: 2a 20 70 29 0a 7b 0a 09 73 74 61 74 69 63 20 69 * p).{..static i
2cc0: 6e 74 20 72 6f 6f 74 63 6f 75 6e 74 20 3d 20 30 nt rootcount = 0
2cd0: 3b 0a 0a 09 72 6f 6f 74 73 20 3d 20 72 65 61 6c ;...roots = real
2ce0: 6c 6f 63 28 72 6f 6f 74 73 2c 20 73 69 7a 65 6f loc(roots, sizeo
2cf0: 66 28 2a 72 6f 6f 74 73 29 2a 28 72 6f 6f 74 63 f(*roots)*(rootc
2d00: 6f 75 6e 74 2b 31 29 29 3b 0a 09 72 6f 6f 74 73 ount+1));..roots
2d10: 5b 72 6f 6f 74 63 6f 75 6e 74 2b 2b 5d 20 3d 20 [rootcount++] =
2d20: 70 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 p;.}..static voi
2d30: 64 20 74 68 72 65 61 64 5f 6d 61 72 6b 28 76 6f d thread_mark(vo
2d40: 69 64 20 2a 20 70 29 0a 7b 0a 09 74 68 72 65 61 id * p).{..threa
2d50: 64 5f 74 20 2a 20 74 68 72 65 61 64 20 3d 20 28 d_t * thread = (
2d60: 74 68 72 65 61 64 5f 74 20 2a 29 70 3b 0a 0a 09 thread_t *)p;...
2d70: 73 6c 61 62 5f 67 63 5f 6d 61 72 6b 28 74 68 72 slab_gc_mark(thr
2d80: 65 61 64 2d 3e 6e 61 6d 65 29 3b 0a 09 69 66 20 ead->name);..if
2d90: 28 74 68 72 65 61 64 2d 3e 73 74 61 74 65 20 21 (thread->state !
2da0: 3d 20 54 48 52 45 41 44 5f 54 45 52 4d 49 4e 41 = THREAD_TERMINA
2db0: 54 45 44 29 20 7b 0a 09 09 2f 2a 20 4d 61 72 6b TED) {.../* Mark
2dc0: 20 6c 69 76 65 20 73 74 61 74 65 20 6f 6e 6c 79 live state only
2dd0: 20 2a 2f 0a 09 09 61 72 63 68 5f 74 68 72 65 61 */...arch_threa
2de0: 64 5f 6d 61 72 6b 28 74 68 72 65 61 64 29 3b 0a d_mark(thread);.
2df0: 09 09 73 6c 61 62 5f 67 63 5f 6d 61 72 6b 5f 62 ..slab_gc_mark_b
2e00: 6c 6f 63 6b 28 74 68 72 65 61 64 2d 3e 74 6c 73 lock(thread->tls
2e10: 2c 20 73 69 7a 65 6f 66 28 74 68 72 65 61 64 2d , sizeof(thread-
2e20: 3e 74 6c 73 29 29 3b 0a 09 09 73 6c 61 62 5f 67 >tls));...slab_g
2e30: 63 5f 6d 61 72 6b 28 74 68 72 65 61 64 2d 3e 70 c_mark(thread->p
2e40: 72 6f 63 65 73 73 29 3b 0a 09 7d 20 65 6c 73 65 rocess);..} else
2e50: 20 7b 0a 09 09 2f 2a 20 4d 61 72 6b 20 64 65 61 {.../* Mark dea
2e60: 64 20 73 74 61 74 65 20 6f 6e 6c 79 20 2a 2f 0a d state only */.
2e70: 09 09 73 6c 61 62 5f 67 63 5f 6d 61 72 6b 28 74 ..slab_gc_mark(t
2e80: 68 72 65 61 64 2d 3e 72 65 74 76 61 6c 29 3b 0a hread->retval);.
2e90: 09 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 .}.}..static voi
2ea0: 64 20 74 68 72 65 61 64 5f 66 69 6e 61 6c 69 7a d thread_finaliz
2eb0: 65 28 76 6f 69 64 20 2a 20 70 29 0a 7b 0a 09 74 e(void * p).{..t
2ec0: 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 hread_t * thread
2ed0: 20 3d 20 28 74 68 72 65 61 64 5f 74 20 2a 29 70 = (thread_t *)p
2ee0: 3b 0a 0a 09 61 72 65 6e 61 5f 74 68 72 65 61 64 ;...arena_thread
2ef0: 5f 66 72 65 65 28 29 3b 0a 09 61 72 63 68 5f 74 _free();..arch_t
2f00: 68 72 65 61 64 5f 66 69 6e 61 6c 69 7a 65 28 74 hread_finalize(t
2f10: 68 72 65 61 64 29 3b 0a 7d 0a 0a 2f 2a 2a 0a 20 hread);.}../**.
2f20: 2a 20 47 65 6e 65 72 61 74 65 20 61 20 66 75 6e * Generate a fun
2f30: 63 74 69 6f 6e 20 63 61 6c 6c 20 73 74 61 63 6b ction call stack
2f40: 20 62 61 63 6b 74 72 61 63 65 0a 20 2a 20 5c 61 backtrace. * \a
2f50: 72 67 20 62 75 66 66 65 72 20 50 6f 69 6e 74 65 rg buffer Pointe
2f60: 72 20 74 6f 20 61 72 72 61 79 20 6f 66 20 70 6f r to array of po
2f70: 69 6e 74 65 72 73 2e 0a 20 2a 20 5c 61 72 67 20 inters.. * \arg
2f80: 6c 65 76 65 6c 73 20 4e 75 6d 62 65 72 20 6f 66 levels Number of
2f90: 20 70 6f 69 6e 74 65 72 73 20 69 6e 20 74 68 65 pointers in the
2fa0: 20 5c 72 65 66 20 62 75 66 66 65 72 20 61 72 72 \ref buffer arr
2fb0: 61 79 2e 0a 20 2a 20 5c 72 65 74 75 72 6e 20 62 ay.. * \return b
2fc0: 75 66 66 65 72 0a 20 2a 2f 0a 76 6f 69 64 20 2a uffer. */.void *
2fd0: 2a 20 74 68 72 65 61 64 5f 62 61 63 6b 74 72 61 * thread_backtra
2fe0: 63 65 28 76 6f 69 64 20 2a 2a 20 62 75 66 66 65 ce(void ** buffe
2ff0: 72 2c 20 69 6e 74 20 6c 65 76 65 6c 73 29 0a 7b r, int levels).{
3000: 0a 09 72 65 74 75 72 6e 20 61 72 63 68 5f 74 68 ..return arch_th
3010: 72 65 61 64 5f 62 61 63 6b 74 72 61 63 65 28 62 read_backtrace(b
3020: 75 66 66 65 72 2c 20 6c 65 76 65 6c 73 29 3b 0a uffer, levels);.
3030: 7d 0a 0a 76 6f 69 64 20 74 68 72 65 61 64 5f 69 }..void thread_i
3040: 6e 69 74 28 29 0a 7b 0a 09 49 4e 49 54 5f 4f 4e nit().{..INIT_ON
3050: 43 45 28 29 3b 0a 0a 09 2f 2a 20 43 72 61 66 74 CE();.../* Craft
3060: 20 61 20 6e 65 77 20 62 6f 6f 74 73 74 72 61 70 a new bootstrap
3070: 20 74 68 72 65 61 64 20 74 6f 20 72 65 70 6c 61 thread to repla
3080: 63 65 20 74 68 65 20 73 74 61 74 69 63 20 64 65 ce the static de
3090: 66 69 6e 65 64 20 74 68 72 65 61 64 20 2a 2f 0a fined thread */.
30a0: 09 61 72 63 68 5f 74 68 72 65 61 64 5f 69 6e 69 .arch_thread_ini
30b0: 74 28 73 6c 61 62 5f 63 61 6c 6c 6f 63 28 74 68 t(slab_calloc(th
30c0: 72 65 61 64 73 29 29 3b 0a 09 74 68 72 65 61 64 reads));..thread
30d0: 5f 74 72 61 63 6b 28 61 72 63 68 5f 67 65 74 5f _track(arch_get_
30e0: 74 68 72 65 61 64 28 29 2c 20 31 29 3b 0a 7d 0a thread(), 1);.}.
30f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 74 68 72 .static void thr
3100: 65 61 64 5f 74 65 73 74 32 28 29 3b 0a 73 74 61 ead_test2();.sta
3110: 74 69 63 20 76 6f 69 64 20 74 68 72 65 61 64 5f tic void thread_
3120: 74 65 73 74 31 28 72 77 6c 6f 63 6b 5f 74 20 2a test1(rwlock_t *
3130: 20 72 77 29 0a 7b 0a 09 76 6f 69 64 20 2a 2a 20 rw).{..void **
3140: 62 74 20 3d 20 74 68 72 65 61 64 5f 62 61 63 6b bt = thread_back
3150: 74 72 61 63 65 28 4e 55 4c 4c 2c 20 31 35 29 3b trace(NULL, 15);
3160: 0a 09 6b 65 72 6e 65 6c 5f 70 72 69 6e 74 6b 28 ..kernel_printk(
3170: 22 74 68 72 65 61 64 5f 74 65 73 74 31 5c 6e 22 "thread_test1\n"
3180: 29 3b 0a 09 77 68 69 6c 65 28 2a 62 74 29 20 7b );..while(*bt) {
3190: 0a 09 09 6b 65 72 6e 65 6c 5f 70 72 69 6e 74 6b ...kernel_printk
31a0: 28 22 5c 74 25 70 5c 6e 22 2c 20 2a 62 74 2b 2b ("\t%p\n", *bt++
31b0: 29 3b 0a 09 7d 0a 0a 09 72 77 6c 6f 63 6b 5f 65 );..}...rwlock_e
31c0: 73 63 61 6c 61 74 65 28 72 77 29 3b 0a 09 72 77 scalate(rw);..rw
31d0: 6c 6f 63 6b 5f 72 65 61 64 28 72 77 29 3b 0a 09 lock_read(rw);..
31e0: 72 77 6c 6f 63 6b 5f 75 6e 6c 6f 63 6b 28 72 77 rwlock_unlock(rw
31f0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 );.}..static voi
3200: 64 20 74 68 72 65 61 64 5f 74 65 73 74 32 28 72 d thread_test2(r
3210: 77 6c 6f 63 6b 5f 74 20 2a 20 72 77 29 0a 7b 0a wlock_t * rw).{.
3220: 09 76 6f 69 64 20 2a 2a 20 62 74 20 3d 20 74 68 .void ** bt = th
3230: 72 65 61 64 5f 62 61 63 6b 74 72 61 63 65 28 4e read_backtrace(N
3240: 55 4c 4c 2c 20 31 35 29 3b 0a 09 6b 65 72 6e 65 ULL, 15);..kerne
3250: 6c 5f 70 72 69 6e 74 6b 28 22 74 68 72 65 61 64 l_printk("thread
3260: 5f 74 65 73 74 32 5c 6e 22 29 3b 0a 09 77 68 69 _test2\n");..whi
3270: 6c 65 28 2a 62 74 29 20 7b 0a 09 09 6b 65 72 6e le(*bt) {...kern
3280: 65 6c 5f 70 72 69 6e 74 6b 28 22 5c 74 25 70 5c el_printk("\t%p\
3290: 6e 22 2c 20 2a 62 74 2b 2b 29 3b 0a 09 7d 0a 09 n", *bt++);..}..
32a0: 72 77 6c 6f 63 6b 5f 75 6e 6c 6f 63 6b 28 72 77 rwlock_unlock(rw
32b0: 29 3b 0a 09 72 77 6c 6f 63 6b 5f 77 72 69 74 65 );..rwlock_write
32c0: 28 72 77 29 3b 0a 09 72 77 6c 6f 63 6b 5f 75 6e (rw);..rwlock_un
32d0: 6c 6f 63 6b 28 72 77 29 3b 0a 7d 0a 0a 73 74 61 lock(rw);.}..sta
32e0: 74 69 63 20 76 6f 69 64 20 74 68 72 65 61 64 5f tic void thread_
32f0: 75 70 64 61 74 65 5f 61 63 63 74 28 63 6f 6e 73 update_acct(cons
3300: 74 20 76 6f 69 64 20 2a 20 63 6f 6e 73 74 20 70 t void * const p
3310: 2c 20 76 6f 69 64 20 2a 20 6b 65 79 2c 20 76 6f , void * key, vo
3320: 69 64 20 2a 20 64 61 74 61 29 0a 7b 0a 09 63 6f id * data).{..co
3330: 6e 73 74 20 74 69 6d 65 72 73 70 65 63 5f 74 20 nst timerspec_t
3340: 2a 70 75 70 74 69 6d 65 20 3d 20 70 3b 0a 09 74 *puptime = p;..t
3350: 68 72 65 61 64 5f 74 20 2a 20 74 68 72 65 61 64 hread_t * thread
3360: 20 3d 20 6b 65 79 3b 0a 09 69 66 20 28 74 68 72 = key;..if (thr
3370: 65 61 64 20 3d 3d 20 61 72 63 68 5f 67 65 74 5f ead == arch_get_
3380: 74 68 72 65 61 64 28 29 29 20 7b 0a 09 09 74 68 thread()) {...th
3390: 72 65 61 64 2d 3e 61 63 63 74 73 5b 74 68 72 65 read->accts[thre
33a0: 61 64 2d 3e 61 63 63 74 5d 2e 74 6c 65 6e 20 3d ad->acct].tlen =
33b0: 20 28 2a 70 75 70 74 69 6d 65 29 20 2d 20 74 68 (*puptime) - th
33c0: 72 65 61 64 2d 3e 61 63 63 74 73 5b 74 68 72 65 read->accts[thre
33d0: 61 64 2d 3e 61 63 63 74 5d 2e 74 73 74 61 72 74 ad->acct].tstart
33e0: 3b 0a 09 09 74 68 72 65 61 64 2d 3e 61 63 63 74 ;...thread->acct
33f0: 2b 2b 3b 0a 09 09 69 66 20 28 73 69 7a 65 6f 66 ++;...if (sizeof
3400: 28 74 68 72 65 61 64 2d 3e 61 63 63 74 73 29 2f (thread->accts)/
3410: 73 69 7a 65 6f 66 28 74 68 72 65 61 64 2d 3e 61 sizeof(thread->a
3420: 63 63 74 73 5b 30 5d 29 20 3d 3d 20 74 68 72 65 ccts[0]) == thre
3430: 61 64 2d 3e 61 63 63 74 29 20 7b 0a 09 09 09 74 ad->acct) {....t
3440: 68 72 65 61 64 2d 3e 61 63 63 74 20 3d 20 30 3b hread->acct = 0;
3450: 0a 09 09 7d 0a 09 7d 0a 09 74 69 6d 65 72 73 70 ...}..}..timersp
3460: 65 63 5f 74 20 73 75 6d 20 3d 20 30 3b 0a 09 74 ec_t sum = 0;..t
3470: 69 6d 65 72 73 70 65 63 5f 74 20 66 72 6f 6d 20 imerspec_t from
3480: 3d 20 28 2a 70 75 70 74 69 6d 65 29 20 2d 20 31 = (*puptime) - 1
3490: 30 30 30 30 30 30 3b 0a 09 66 6f 72 28 69 6e 74 000000;..for(int
34a0: 20 69 3d 30 3b 20 69 3c 63 6f 75 6e 74 6f 66 28 i=0; i<countof(
34b0: 74 68 72 65 61 64 2d 3e 61 63 63 74 73 29 3b 20 thread->accts);
34c0: 69 2b 2b 29 20 7b 0a 09 09 74 69 6d 65 72 73 70 i++) {...timersp
34d0: 65 63 5f 74 20 61 63 63 74 73 74 61 72 74 20 3d ec_t acctstart =
34e0: 20 74 68 72 65 61 64 2d 3e 61 63 63 74 73 5b 69 thread->accts[i
34f0: 5d 2e 74 73 74 61 72 74 3b 0a 09 09 74 69 6d 65 ].tstart;...time
3500: 72 73 70 65 63 5f 74 20 61 63 63 74 65 6e 64 20 rspec_t acctend
3510: 3d 20 61 63 63 74 73 74 61 72 74 20 2b 20 74 68 = acctstart + th
3520: 72 65 61 64 2d 3e 61 63 63 74 73 5b 69 5d 2e 74 read->accts[i].t
3530: 6c 65 6e 3b 0a 09 09 69 66 20 28 61 63 63 74 73 len;...if (accts
3540: 74 61 72 74 20 3e 20 66 72 6f 6d 29 20 7b 0a 09 tart > from) {..
3550: 09 09 73 75 6d 20 2b 3d 20 28 61 63 63 74 65 6e ..sum += (accten
3560: 64 20 2d 20 61 63 63 74 73 74 61 72 74 29 3b 0a d - acctstart);.
3570: 09 09 7d 20 65 6c 73 65 20 69 66 20 28 61 63 63 ..} else if (acc
3580: 74 65 6e 64 20 3e 20 66 72 6f 6d 29 20 7b 0a 09 tend > from) {..
3590: 09 09 73 75 6d 20 2b 3d 20 28 61 63 63 74 65 6e ..sum += (accten
35a0: 64 20 2d 20 66 72 6f 6d 29 3b 0a 09 09 7d 0a 09 d - from);...}..
35b0: 7d 0a 09 74 68 72 65 61 64 2d 3e 75 73 61 67 65 }..thread->usage
35c0: 20 3d 20 73 75 6d 3b 0a 0a 09 69 6e 74 20 70 65 = sum;...int pe
35d0: 72 63 65 6e 74 20 3d 20 31 30 30 20 2a 20 74 68 rcent = 100 * th
35e0: 72 65 61 64 2d 3e 75 73 61 67 65 20 2f 20 31 30 read->usage / 10
35f0: 30 30 30 30 30 3b 0a 09 6b 65 72 6e 65 6c 5f 70 00000;..kernel_p
3600: 72 69 6e 74 6b 28 22 25 73 3a 20 25 64 5c 6e 22 rintk("%s: %d\n"
3610: 2c 20 74 68 72 65 61 64 2d 3e 6e 61 6d 65 20 3f , thread->name ?
3620: 20 74 68 72 65 61 64 2d 3e 6e 61 6d 65 20 3a 20 thread->name :
3630: 22 55 6e 6b 6e 6f 77 6e 22 2c 20 70 65 72 63 65 "Unknown", perce
3640: 6e 74 29 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 nt);.}..typedef
3650: 73 74 72 75 63 74 20 74 68 72 65 61 64 5f 70 6f struct thread_po
3660: 6f 6c 5f 72 65 71 75 65 73 74 5f 74 20 74 68 72 ol_request_t thr
3670: 65 61 64 5f 70 6f 6f 6c 5f 72 65 71 75 65 73 74 ead_pool_request
3680: 5f 74 3b 0a 73 74 72 75 63 74 20 74 68 72 65 61 _t;.struct threa
3690: 64 5f 70 6f 6f 6c 5f 72 65 71 75 65 73 74 5f 74 d_pool_request_t
36a0: 20 7b 0a 09 76 6f 69 64 20 28 2a 66 75 6e 63 74 {..void (*funct
36b0: 69 6f 6e 29 28 76 6f 69 64 20 2a 20 61 72 67 29 ion)(void * arg)
36c0: 3b 0a 09 76 6f 69 64 20 2a 20 61 72 67 3b 0a 7d ;..void * arg;.}
36d0: 3b 0a 0a 76 6f 69 64 20 2a 20 74 68 72 65 61 64 ;..void * thread
36e0: 5f 70 6f 6f 6c 5f 70 72 6f 63 65 73 73 6f 72 28 _pool_processor(
36f0: 76 6f 69 64 20 2a 20 70 29 0a 7b 0a 09 74 68 72 void * p).{..thr
3700: 65 61 64 5f 70 6f 6f 6c 5f 74 20 2a 20 70 6f 6f ead_pool_t * poo
3710: 6c 20 3d 20 70 3b 0a 09 77 68 69 6c 65 28 31 29 l = p;..while(1)
3720: 20 7b 0a 09 09 74 68 72 65 61 64 5f 70 6f 6f 6c {...thread_pool
3730: 5f 72 65 71 75 65 73 74 5f 74 20 2a 20 72 65 71 _request_t * req
3740: 75 65 73 74 20 3d 20 71 75 65 75 65 5f 67 65 74 uest = queue_get
3750: 70 28 70 6f 6f 6c 2d 3e 71 75 65 75 65 29 3b 0a p(pool->queue);.
3760: 09 09 4b 54 52 59 20 7b 0a 09 09 09 72 65 71 75 ..KTRY {....requ
3770: 65 73 74 2d 3e 66 75 6e 63 74 69 6f 6e 28 72 65 est->function(re
3780: 71 75 65 73 74 2d 3e 61 72 67 29 3b 0a 09 09 7d quest->arg);...}
3790: 20 4b 43 41 54 43 48 28 54 68 72 6f 77 61 62 6c KCATCH(Throwabl
37a0: 65 29 20 7b 0a 09 09 09 65 78 63 65 70 74 69 6f e) {....exceptio
37b0: 6e 5f 6c 6f 67 28 29 3b 0a 09 09 7d 0a 09 7d 0a n_log();...}..}.
37c0: 7d 0a 0a 74 68 72 65 61 64 5f 70 6f 6f 6c 5f 74 }..thread_pool_t
37d0: 20 2a 20 74 68 72 65 61 64 5f 70 6f 6f 6c 5f 63 * thread_pool_c
37e0: 72 65 61 74 65 28 29 0a 7b 0a 09 74 68 72 65 61 reate().{..threa
37f0: 64 5f 70 6f 6f 6c 5f 74 20 2a 20 70 6f 6f 6c 20 d_pool_t * pool
3800: 3d 20 63 61 6c 6c 6f 63 28 31 2c 20 73 69 7a 65 = calloc(1, size
3810: 6f 66 28 2a 70 6f 6f 6c 29 29 3b 0a 09 70 6f 6f of(*pool));..poo
3820: 6c 2d 3e 71 75 65 75 65 20 3d 20 71 75 65 75 65 l->queue = queue
3830: 5f 6e 65 77 28 31 36 29 3b 0a 09 70 6f 6f 6c 2d _new(16);..pool-
3840: 3e 74 68 72 65 61 64 20 3d 20 74 68 72 65 61 64 >thread = thread
3850: 5f 73 70 61 77 6e 28 74 68 72 65 61 64 5f 70 6f _spawn(thread_po
3860: 6f 6c 5f 70 72 6f 63 65 73 73 6f 72 2c 20 70 6f ol_processor, po
3870: 6f 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 20 70 6f ol);...return po
3880: 6f 6c 3b 0a 7d 0a 0a 76 6f 69 64 20 74 68 72 65 ol;.}..void thre
3890: 61 64 5f 70 6f 6f 6c 5f 73 75 62 6d 69 74 28 74 ad_pool_submit(t
38a0: 68 72 65 61 64 5f 70 6f 6f 6c 5f 74 20 2a 20 70 hread_pool_t * p
38b0: 6f 6f 6c 2c 20 76 6f 69 64 20 28 2a 66 75 6e 63 ool, void (*func
38c0: 74 69 6f 6e 29 28 76 6f 69 64 20 2a 20 61 72 67 tion)(void * arg
38d0: 29 2c 20 76 6f 69 64 20 2a 20 61 72 67 29 0a 7b ), void * arg).{
38e0: 0a 09 73 74 61 74 69 63 20 47 43 52 4f 4f 54 20 ..static GCROOT
38f0: 74 68 72 65 61 64 5f 70 6f 6f 6c 5f 74 20 2a 20 thread_pool_t *
3900: 64 65 66 61 75 6c 74 70 6f 6f 6c 3b 0a 0a 09 69 defaultpool;...i
3910: 66 20 28 30 20 3d 3d 20 70 6f 6f 6c 29 20 7b 0a f (0 == pool) {.
3920: 09 09 69 66 20 28 64 65 66 61 75 6c 74 70 6f 6f ..if (defaultpoo
3930: 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 09 64 65 66 l == 0) {....def
3940: 61 75 6c 74 70 6f 6f 6c 20 3d 20 74 68 72 65 61 aultpool = threa
3950: 64 5f 70 6f 6f 6c 5f 63 72 65 61 74 65 28 29 3b d_pool_create();
3960: 0a 09 09 7d 0a 09 09 70 6f 6f 6c 20 3d 20 64 65 ...}...pool = de
3970: 66 61 75 6c 74 70 6f 6f 6c 3b 0a 09 7d 0a 0a 09 faultpool;..}...
3980: 74 68 72 65 61 64 5f 70 6f 6f 6c 5f 72 65 71 75 thread_pool_requ
3990: 65 73 74 5f 74 20 72 65 71 75 65 73 74 20 3d 20 est_t request =
39a0: 7b 2e 66 75 6e 63 74 69 6f 6e 20 3d 20 66 75 6e {.function = fun
39b0: 63 74 69 6f 6e 2c 20 2e 61 72 67 20 3d 20 61 72 ction, .arg = ar
39c0: 67 7d 3b 0a 0a 09 71 75 65 75 65 5f 70 75 74 70 g};...queue_putp
39d0: 28 70 6f 6f 6c 2d 3e 71 75 65 75 65 2c 20 6d 63 (pool->queue, mc
39e0: 6c 6f 6e 65 28 26 72 65 71 75 65 73 74 29 29 3b lone(&request));
39f0: 0a 7d 0a 0a 76 6f 69 64 20 74 68 72 65 61 64 5f .}..void thread_
3a00: 75 70 64 61 74 65 5f 61 63 63 74 73 28 29 0a 7b update_accts().{
3a10: 0a 09 53 50 49 4e 5f 41 55 54 4f 4c 4f 43 4b 28 ..SPIN_AUTOLOCK(
3a20: 26 61 6c 6c 74 68 72 65 61 64 73 6c 6f 63 6b 29 &allthreadslock)
3a30: 20 7b 0a 09 09 74 69 6d 65 72 73 70 65 63 5f 74 {...timerspec_t
3a40: 20 75 70 74 69 6d 65 20 3d 20 74 69 6d 65 72 5f uptime = timer_
3a50: 75 70 74 69 6d 65 28 31 29 3b 0a 09 09 69 66 20 uptime(1);...if
3a60: 28 61 6c 6c 74 68 72 65 61 64 73 29 20 7b 0a 09 (allthreads) {..
3a70: 09 09 6d 61 70 5f 77 61 6c 6b 70 70 28 61 6c 6c ..map_walkpp(all
3a80: 74 68 72 65 61 64 73 2c 20 74 68 72 65 61 64 5f threads, thread_
3a90: 75 70 64 61 74 65 5f 61 63 63 74 2c 20 26 75 70 update_acct, &up
3aa0: 74 69 6d 65 29 3b 0a 09 09 7d 0a 09 7d 0a 7d 0a time);...}..}.}.
3ab0: 0a 76 6f 69 64 20 74 68 72 65 61 64 5f 74 65 73 .void thread_tes
3ac0: 74 28 29 0a 7b 0a 09 74 68 72 65 61 64 5f 74 20 t().{..thread_t
3ad0: 2a 20 74 68 72 65 61 64 31 3b 0a 0a 09 74 68 72 * thread1;...thr
3ae0: 65 61 64 31 20 3d 20 74 68 72 65 61 64 5f 66 6f ead1 = thread_fo
3af0: 72 6b 28 29 3b 0a 09 69 66 20 28 74 68 72 65 61 rk();..if (threa
3b00: 64 31 29 20 7b 0a 09 09 74 68 72 65 61 64 5f 6a d1) {...thread_j
3b10: 6f 69 6e 28 74 68 72 65 61 64 31 29 3b 0a 09 09 oin(thread1);...
3b20: 74 68 72 65 61 64 31 20 3d 20 30 3b 0a 09 7d 20 thread1 = 0;..}
3b30: 65 6c 73 65 20 7b 0a 09 09 73 74 61 74 69 63 20 else {...static
3b40: 72 77 6c 6f 63 6b 5f 74 20 72 77 5b 31 5d 20 3d rwlock_t rw[1] =
3b50: 20 7b 30 7d 3b 0a 09 09 74 68 72 65 61 64 5f 74 {0};...thread_t
3b60: 20 2a 20 74 68 72 65 61 64 32 20 3d 20 74 68 72 * thread2 = thr
3b70: 65 61 64 5f 66 6f 72 6b 28 29 3b 0a 09 09 72 77 ead_fork();...rw
3b80: 6c 6f 63 6b 5f 72 65 61 64 28 72 77 29 3b 0a 09 lock_read(rw);..
3b90: 09 69 66 20 28 74 68 72 65 61 64 32 29 20 7b 0a .if (thread2) {.
3ba0: 09 09 09 74 68 72 65 61 64 5f 74 65 73 74 31 28 ...thread_test1(
3bb0: 72 77 29 3b 0a 09 09 09 74 68 72 65 61 64 5f 6a rw);....thread_j
3bc0: 6f 69 6e 28 74 68 72 65 61 64 32 29 3b 0a 09 09 oin(thread2);...
3bd0: 09 74 68 72 65 61 64 32 20 3d 20 30 3b 0a 09 09 .thread2 = 0;...
3be0: 09 74 68 72 65 61 64 5f 65 78 69 74 28 30 29 3b .thread_exit(0);
3bf0: 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 74 ...} else {....t
3c00: 68 72 65 61 64 5f 74 65 73 74 32 28 72 77 29 3b hread_test2(rw);
3c10: 0a 09 09 09 74 68 72 65 61 64 5f 65 78 69 74 28 ....thread_exit(
3c20: 30 29 3b 0a 09 09 7d 0a 09 7d 0a 7d 0a 0);...}..}.}.