/* * Copyright (c) 2017 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _KERN_THREAD_I_H #define _KERN_THREAD_I_H #include #include #include #include #include #include #include #include struct thread_runq; struct thread_fs_runq; /* * Thread flags. */ #define THREAD_YIELD 0x1UL /* Must yield the processor ASAP */ #define THREAD_DETACHED 0x2UL /* Resources automatically released on exit */ /* * Thread states. * * Threads in the running state may not be on a run queue if they're being * awaken. */ #define THREAD_RUNNING 0 #define THREAD_SLEEPING 1 #define THREAD_DEAD 2 /* * Scheduling data for a real-time thread. */ struct thread_rt_data { struct list node; unsigned short time_slice; }; /* * Scheduling data for a fair-scheduling thread. */ struct thread_fs_data { struct list group_node; struct list runq_node; struct thread_fs_runq *fs_runq; unsigned long round; unsigned short weight; unsigned short work; }; /* * Common scheduling data. */ struct thread_sched_data { unsigned char sched_policy; unsigned char sched_class; unsigned short priority; }; /* * Maximum number of thread-specific data keys. */ #define THREAD_KEYS_MAX 4 /* * Thread structure. * * Thread members are normally protected by the lock of the run queue they're * associated with. Thread-local members are accessed without synchronization. */ struct thread { struct tcb tcb; /* Flags must be changed atomically */ unsigned long flags; /* Sleep/wakeup synchronization members */ struct thread_runq *runq; unsigned short state; /* Thread-local members */ unsigned short preempt; unsigned short pinned; unsigned short llsync_read; /* Processors on which this thread is allowed to run */ struct cpumap cpumap; /* Scheduling data */ struct thread_sched_data sched_data; /* Class specific scheduling data */ union { struct thread_rt_data rt_data; struct thread_fs_data fs_data; }; /* * Thread-specific data should only be used by architecture-dependent code. * For machine-independent code, new member variables should be added. * * TODO move those to the TCB and remove. */ void *tsd[THREAD_KEYS_MAX]; /* Members related to termination */ struct mutex join_lock; struct condition join_cond; int exited; /* Read-only members */ struct task *task; struct list task_node; void *stack; char name[THREAD_NAME_SIZE]; void (*fn)(void *); void *arg; } __aligned(CPU_L1_SIZE); #define THREAD_ATTR_DETACHED 0x1 /* * Flag access functions. */ static inline void thread_set_flag(struct thread *thread, unsigned long flag) { atomic_or_ulong(&thread->flags, flag); } static inline void thread_clear_flag(struct thread *thread, unsigned long flag) { atomic_and_ulong(&thread->flags, ~flag); } static inline int thread_test_flag(struct thread *thread, unsigned long flag) { barrier(); return ((thread->flags & flag) != 0); } #endif /* _KERN_THREAD_I_H */