1:
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
31:
32: #ifndef _SYS_LWP_H_
33: #define _SYS_LWP_H_
34:
35: #include <sys/time.h>
36: #ifndef T2EX
37: #include <sys/queue.h>
38: #else
39: #include <sys/_queue.h>
40: #endif
41: #include <sys/callout.h>
42: #include <sys/mutex.h>
43: #include <sys/condvar.h>
44: #ifndef T2EX
45: #include <sys/signalvar.h>
46: #include <sys/sched.h>
47: #endif
48: #include <sys/specificdata.h>
49: #include <sys/syncobj.h>
50: #include <sys/resource.h>
51:
52: #ifndef T2EX
53: #if defined(_KERNEL)
54: #include <machine/cpu.h>
55: #endif
56:
57: #include <machine/proc.h>
58: #endif
59:
60: #ifdef T2EX
61: struct lwp {
62: struct proc *l_proc;
63:
64: kmutex_t * volatile l_mutex;
65: int l_stat;
66:
67: int l_selflag;
68: SLIST_HEAD(,selinfo) l_selwait;
69: struct selcpu *l_selcpu;
70: struct filedesc *l_fd;
71: int l_dupfd;
72:
73:
74: TAILQ_ENTRY(lwp) l_sleepchain;
75: wchan_t l_wchan;
76: struct sleepq *l_sleepq;
77: callout_t l_timeout_ch;
78:
79: int is_waiting;
80:
81: };
82: #else
83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98:
99: struct lockdebug;
100: struct sadata_vp;
101: struct sysent;
102:
103: struct lwp {
104:
105: TAILQ_ENTRY(lwp) l_runq;
106: union {
107: void * info;
108: u_int timeslice;
109: } l_sched;
110: struct cpu_info *volatile l_cpu;
111: kmutex_t * volatile l_mutex;
112: int l_ctxswtch;
113: struct user *l_addr;
114: struct mdlwp l_md;
115: int l_flag;
116: int l_stat;
117: struct bintime l_rtime;
118: struct bintime l_stime;
119: u_int l_swtime;
120: u_int l_holdcnt;
121: u_int l_rticks;
122: u_int l_rticksum;
123: u_int l_slpticks;
124: u_int l_slpticksum;
125: int l_biglocks;
126: int l_class;
127: int l_kpriority;
128: pri_t l_kpribase;
129: pri_t l_priority;
130: pri_t l_inheritedprio;
131: SLIST_HEAD(, turnstile) l_pi_lenders;
132: uint64_t l_ncsw;
133: uint64_t l_nivcsw;
134: u_int l_cpticks;
135: fixpt_t l_pctcpu;
136: fixpt_t l_estcpu;
137: psetid_t l_psid;
138: struct cpu_info *l_target_cpu;
139: kmutex_t l_swaplock;
140: struct lwpctl *l_lwpctl;
141: struct lcpage *l_lcpage;
142: kcpuset_t *l_affinity;
143: struct sadata_vp *l_savp;
144:
145:
146: struct turnstile *l_ts;
147: struct syncobj *l_syncobj;
148: TAILQ_ENTRY(lwp) l_sleepchain;
149: wchan_t l_wchan;
150: const char *l_wmesg;
151: struct sleepq *l_sleepq;
152: int l_sleeperr;
153: u_int l_slptime;
154: callout_t l_timeout_ch;
155:
156:
157: LIST_ENTRY(lwp) l_list;
158: void *l_ctxlink;
159: struct proc *l_proc;
160: LIST_ENTRY(lwp) l_sibling;
161: lwpid_t l_waiter;
162: lwpid_t l_waitingfor;
163: int l_prflag;
164: u_int l_refcnt;
165: lwpid_t l_lid;
166: int l_selflag;
167: SLIST_HEAD(,selinfo) l_selwait;
168: struct selcpu *l_selcpu;
169: char *l_name;
170:
171:
172: int l_sigrestore;
173: sigset_t l_sigwaitset;
174: kcondvar_t l_sigcv;
175: struct ksiginfo *l_sigwaited;
176: sigpend_t *l_sigpendset;
177: LIST_ENTRY(lwp) l_sigwaiter;
178: stack_t l_sigstk;
179: sigset_t l_sigmask;
180: sigpend_t l_sigpend;
181: sigset_t l_sigoldmask;
182:
183:
184: specificdata_reference
185: l_specdataref;
186: union {
187: struct timeval tv;
188: struct timespec ts;
189: } l_ktrcsw;
190: void *l_private;
191: struct lwp *l_switchto;
192: struct kauth_cred *l_cred;
193: struct filedesc *l_fd;
194: void *l_emuldata;
195: u_int l_cv_signalled;
196: u_short l_shlocks;
197: u_short l_exlocks;
198: u_short l_unused;
199: u_short l_blcnt;
200: int l_nopreempt;
201: u_int l_dopreempt;
202: int l_pflag;
203: int l_dupfd;
204: const struct sysent * volatile l_sysent;
205: struct rusage l_ru;
206: uint64_t l_pfailtime;
207: uintptr_t l_pfailaddr;
208: uintptr_t l_pfaillock;
209: _TAILQ_HEAD(,struct lockdebug,volatile) l_ld_locks;
210:
211:
212: uint32_t l_syscall_time;
213: uint64_t *l_syscall_counter;
214: };
215:
216: #if !defined(USER_TO_UAREA)
217: #if !defined(UAREA_USER_OFFSET)
218: #define UAREA_USER_OFFSET 0
219: #endif
220: #define USER_TO_UAREA(user) ((vaddr_t)(user) - UAREA_USER_OFFSET)
221: #define UAREA_TO_USER(uarea) ((struct user *)((uarea) + UAREA_USER_OFFSET))
222: #endif
223:
224: LIST_HEAD(lwplist, lwp);
225: #endif
226:
227: #ifdef _KERNEL
228: #ifndef T2EX
229: extern kmutex_t alllwp_mutex;
230: extern struct lwplist alllwp;
231:
232: extern struct pool lwp_uc_pool;
233: #endif
234: extern lwp_t lwp0;
235: #endif
236:
237:
238: #define LW_IDLE 0x00000001
239: #define LW_INMEM 0x00000004
240: #define LW_SINTR 0x00000080
241: #define LW_SA_SWITCHING 0x00000100
242: #define LW_SYSTEM 0x00000200
243: #define LW_SA 0x00000400
244: #define LW_WSUSPEND 0x00020000
245: #define LW_BATCH 0x00040000
246: #define LW_WCORE 0x00080000
247: #define LW_WEXIT 0x00100000
248: #define LW_AFFINITY 0x00200000
249: #define LW_SA_UPCALL 0x00400000
250: #define LW_SA_BLOCKING 0x00800000
251: #define LW_PENDSIG 0x01000000
252: #define LW_CANCELLED 0x02000000
253: #define LW_WUSERRET 0x04000000
254: #define LW_WREBOOT 0x08000000
255: #define LW_UNPARKED 0x10000000
256: #define LW_SA_YIELD 0x40000000
257: #define LW_SA_IDLE 0x80000000
258:
259:
260: #define LP_KTRACTIVE 0x00000001
261: #define LP_KTRCSW 0x00000002
262: #define LP_KTRCSWUSER 0x00000004
263: #define LP_OWEUPC 0x00000010
264: #define LP_MPSAFE 0x00000020
265: #define LP_INTR 0x00000040
266: #define LP_SYSCTLWRITE 0x00000080
267: #define LP_SA_PAGEFAULT 0x00000200
268: #define LP_SA_NOBLOCK 0x00000400
269: #define LP_TIMEINTR 0x00010000
270: #define LP_RUNNING 0x20000000
271: #define LP_BOUND 0x80000000
272:
273: #ifndef T2EX
274:
275: #define LPR_DETACHED 0x00800000
276: #define LPR_CRMOD 0x00000100
277:
278: 279: 280: 281:
282: #define LW_USERRET (LW_WEXIT|LW_PENDSIG|LW_WREBOOT|LW_WSUSPEND|LW_WCORE|\
283: LW_WUSERRET|LW_SA_BLOCKING|LW_SA_UPCALL)
284: #endif
285:
286: 287: 288: 289: 290: 291: 292: 293:
294: #define LSIDL 1
295: #define LSRUN 2
296: #define LSSLEEP 3
297: #define LSSTOP 4
298: #define LSZOMB 5
299:
300: #define LSDEAD 6
301: #define LSONPROC 7
302: #define LSSUSPENDED 8
303:
304: #ifdef _KERNEL
305: #ifndef T2EX
306: #define LWP_CACHE_CREDS(l, p) \
307: do { \
308: (void)p; \
309: if (__predict_false((l)->l_prflag & LPR_CRMOD)) \
310: lwp_update_creds(l); \
311: } while ( 0)
312:
313: void lwp_startup(lwp_t *, lwp_t *);
314:
315: int lwp_locked(lwp_t *, kmutex_t *);
316: void lwp_setlock(lwp_t *, kmutex_t *);
317: void lwp_unlock_to(lwp_t *, kmutex_t *);
318: #endif
319: kmutex_t *lwp_lock_retry(lwp_t *, kmutex_t *);
320: #ifndef T2EX
321: void lwp_relock(lwp_t *, kmutex_t *);
322: int lwp_trylock(lwp_t *);
323: void lwp_addref(lwp_t *);
324: void lwp_delref(lwp_t *);
325: void lwp_drainrefs(lwp_t *);
326: bool lwp_alive(lwp_t *);
327: lwp_t *lwp_find_first(proc_t *);
328:
329:
330: #define LWPWAIT_EXITCONTROL 0x00000001
331: void lwpinit(void);
332: int lwp_wait1(lwp_t *, lwpid_t, lwpid_t *, int);
333: void lwp_continue(lwp_t *);
334: void cpu_setfunc(lwp_t *, void (*)(void *), void *);
335: void startlwp(void *);
336: void upcallret(lwp_t *);
337: void lwp_exit(lwp_t *) __dead;
338: void lwp_exit_switchaway(lwp_t *) __dead;
339: int lwp_suspend(lwp_t *, lwp_t *);
340: int lwp_create1(lwp_t *, const void *, size_t, u_long, lwpid_t *);
341: void lwp_update_creds(lwp_t *);
342: void lwp_migrate(lwp_t *, struct cpu_info *);
343: lwp_t *lwp_find2(pid_t, lwpid_t);
344: lwp_t *lwp_find(proc_t *, int);
345: void lwp_userret(lwp_t *);
346: void lwp_need_userret(lwp_t *);
347: void lwp_free(lwp_t *, bool, bool);
348: void lwp_sys_init(void);
349: u_int lwp_unsleep(lwp_t *, bool);
350:
351: int lwp_specific_key_create(specificdata_key_t *, specificdata_dtor_t);
352: void lwp_specific_key_delete(specificdata_key_t);
353: void lwp_initspecific(lwp_t *);
354: void lwp_finispecific(lwp_t *);
355: void *lwp_getspecific(specificdata_key_t);
356: #if defined(_LWP_API_PRIVATE)
357: void *_lwp_getspecific_by_lwp(lwp_t *, specificdata_key_t);
358: #endif
359: void lwp_setspecific(specificdata_key_t, void *);
360:
361:
362: int lwp_park(struct timespec *, const void *);
363: int lwp_unpark(lwpid_t, const void *);
364:
365:
366: void lwp_whatis(uintptr_t, void (*)(const char *, ...));
367:
368: #endif
369: 370: 371:
372: static inline void
373: lwp_lock(lwp_t *l)
374: {
375: kmutex_t *old;
376:
377: mutex_spin_enter(old = l->l_mutex);
378:
379: 380: 381: 382:
383: if (__predict_false(l->l_mutex != old))
384: lwp_lock_retry(l, old);
385: }
386:
387: 388: 389:
390: static inline void
391: lwp_unlock(lwp_t *l)
392: {
393: mutex_spin_exit(l->l_mutex);
394: }
395:
396: #ifndef T2EX
397: static inline void
398: lwp_changepri(lwp_t *l, pri_t pri)
399: {
400: KASSERT(mutex_owned(l->l_mutex));
401:
402: (*l->l_syncobj->sobj_changepri)(l, pri);
403: }
404:
405: static inline void
406: lwp_lendpri(lwp_t *l, pri_t pri)
407: {
408: KASSERT(mutex_owned(l->l_mutex));
409:
410: if (l->l_inheritedprio == pri)
411: return;
412:
413: (*l->l_syncobj->sobj_lendpri)(l, pri);
414: }
415:
416: static inline pri_t
417: lwp_eprio(lwp_t *l)
418: {
419: pri_t pri;
420:
421: pri = l->l_priority;
422: if (l->l_kpriority && pri < PRI_KERNEL)
423: pri = (pri >> 1) + l->l_kpribase;
424: return MAX(l->l_inheritedprio, pri);
425: }
426:
427: int lwp_create(lwp_t *, struct proc *, vaddr_t, bool, int,
428: void *, size_t, void (*)(void *), void *, lwp_t **, int);
429:
430: 431: 432:
433:
434: static inline void
435: spc_lock(struct cpu_info *ci)
436: {
437: mutex_spin_enter(ci->ci_schedstate.spc_mutex);
438: }
439:
440: static inline void
441: spc_unlock(struct cpu_info *ci)
442: {
443: mutex_spin_exit(ci->ci_schedstate.spc_mutex);
444: }
445:
446: static inline void
447: spc_dlock(struct cpu_info *ci1, struct cpu_info *ci2)
448: {
449: struct schedstate_percpu *spc1 = &ci1->ci_schedstate;
450: struct schedstate_percpu *spc2 = &ci2->ci_schedstate;
451:
452: KASSERT(ci1 != ci2);
453: if (ci1 < ci2) {
454: mutex_spin_enter(spc1->spc_mutex);
455: mutex_spin_enter(spc2->spc_mutex);
456: } else {
457: mutex_spin_enter(spc2->spc_mutex);
458: mutex_spin_enter(spc1->spc_mutex);
459: }
460: }
461: #endif
462: #endif
463:
464: #ifdef _KERNEL
465: 466: 467: 468:
469: #if !defined(curlwp)
470: #ifndef T2EX
471: #if defined(MULTIPROCESSOR)
472: #define curlwp curcpu()->ci_curlwp
473: #else
474: extern struct lwp *curlwp;
475: #endif
476: #else
477: lwp_t* tkn_curlwp(void);
478: #define curlwp tkn_curlwp()
479: #endif
480: #endif
481: #define curproc (curlwp->l_proc)
482: #endif
483:
484: #ifndef T2EX
485: #ifdef _KERNEL
486: static inline bool
487: CURCPU_IDLE_P(void)
488: {
489: struct cpu_info *ci = curcpu();
490: return ci->ci_data.cpu_onproc == ci->ci_data.cpu_idlelwp;
491: }
492:
493: 494: 495: 496: 497: 498:
499: static inline void
500: KPREEMPT_DISABLE(lwp_t *l)
501: {
502:
503: KASSERT(l == curlwp);
504: l->l_nopreempt++;
505: __insn_barrier();
506: }
507:
508: static inline void
509: KPREEMPT_ENABLE(lwp_t *l)
510: {
511:
512: KASSERT(l == curlwp);
513: KASSERT(l->l_nopreempt > 0);
514: __insn_barrier();
515: if (--l->l_nopreempt != 0)
516: return;
517: __insn_barrier();
518: if (__predict_false(l->l_dopreempt))
519: kpreempt(0);
520: __insn_barrier();
521: }
522:
523:
524: #define DOPREEMPT_ACTIVE 0x01
525: #define DOPREEMPT_COUNTED 0x02
526:
527: #endif
528:
529:
530: #define LWP_DETACHED 0x00000040
531: #define LWP_SUSPENDED 0x00000080
532: #define LWP_VFORK 0x80000000
533: #endif
534:
535: #endif