1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright 2015 Intel Corporation.
4  * Copyright 2012 Hasan Alayli <[email protected]>
5  */
6 #ifndef LTHREAD_INT_H
7 #define LTHREAD_INT_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <stdint.h>
14 #include <sys/time.h>
15 #include <sys/types.h>
16 #include <errno.h>
17 #include <pthread.h>
18 #include <time.h>
19 
20 #include <rte_memory.h>
21 #include <rte_cycles.h>
22 #include <rte_per_lcore.h>
23 #include <rte_timer.h>
24 #include <rte_atomic_64.h>
25 #include <rte_spinlock.h>
26 #include <ctx.h>
27 
28 #include <lthread_api.h>
29 #include "lthread.h"
30 #include "lthread_diag.h"
31 #include "lthread_tls.h"
32 
33 struct lthread;
34 struct lthread_sched;
35 struct lthread_cond;
36 struct lthread_mutex;
37 struct lthread_key;
38 
39 struct key_pool;
40 struct qnode;
41 struct qnode_pool;
42 struct lthread_sched;
43 struct lthread_tls;
44 
45 
46 #define BIT(x) (1 << (x))
47 #define CLEARBIT(x) ~(1 << (x))
48 
49 #define POSIX_ERRNO(x)  (x)
50 
51 #define MAX_LTHREAD_NAME_SIZE 64
52 
53 #define RTE_LOGTYPE_LTHREAD RTE_LOGTYPE_USER1
54 
55 
56 /* define some shorthand for current scheduler and current thread */
57 #define THIS_SCHED RTE_PER_LCORE(this_sched)
58 #define THIS_LTHREAD RTE_PER_LCORE(this_sched)->current_lthread
59 
60 /*
61  * Definition of an scheduler struct
62  */
63 struct lthread_sched {
64 	struct ctx ctx;					/* cpu context */
65 	uint64_t birth;					/* time created */
66 	struct lthread *current_lthread;		/* running thread */
67 	unsigned lcore_id;				/* this sched lcore */
68 	int run_flag;					/* sched shutdown */
69 	uint64_t nb_blocked_threads;	/* blocked threads */
70 	struct lthread_queue *ready;			/* local ready queue */
71 	struct lthread_queue *pready;			/* peer ready queue */
72 	struct lthread_objcache *lthread_cache;		/* free lthreads */
73 	struct lthread_objcache *stack_cache;		/* free stacks */
74 	struct lthread_objcache *per_lthread_cache;	/* free per lthread */
75 	struct lthread_objcache *tls_cache;		/* free TLS */
76 	struct lthread_objcache *cond_cache;		/* free cond vars */
77 	struct lthread_objcache *mutex_cache;		/* free mutexes */
78 	struct qnode_pool *qnode_pool;		/* pool of queue nodes */
79 	struct key_pool *key_pool;		/* pool of free TLS keys */
80 	size_t stack_size;
81 	uint64_t diag_ref;				/* diag ref */
82 } __rte_cache_aligned;
83 
84 RTE_DECLARE_PER_LCORE(struct lthread_sched *, this_sched);
85 
86 
87 /*
88  * State for an lthread
89  */
90 enum lthread_st {
91 	ST_LT_INIT,		/* initial state */
92 	ST_LT_READY,		/* lthread is ready to run */
93 	ST_LT_SLEEPING,		/* lthread is sleeping */
94 	ST_LT_EXPIRED,		/* lthread timeout has expired  */
95 	ST_LT_EXITED,		/* lthread has exited and needs cleanup */
96 	ST_LT_DETACH,		/* lthread frees on exit*/
97 	ST_LT_CANCELLED,	/* lthread has been cancelled */
98 };
99 
100 /*
101  * lthread sub states for exit/join
102  */
103 enum join_st {
104 	LT_JOIN_INITIAL,	/* initial state */
105 	LT_JOIN_EXITING,	/* thread is exiting */
106 	LT_JOIN_THREAD_SET,	/* joining thread has been set */
107 	LT_JOIN_EXIT_VAL_SET,	/* exiting thread has set ret val */
108 	LT_JOIN_EXIT_VAL_READ,	/* joining thread has collected ret val */
109 };
110 
111 /* defnition of an lthread stack object */
112 struct lthread_stack {
113 	uint8_t stack[LTHREAD_MAX_STACK_SIZE];
114 	size_t stack_size;
115 	struct lthread_sched *root_sched;
116 } __rte_cache_aligned;
117 
118 /*
119  * Definition of an lthread
120  */
121 struct lthread {
122 	struct ctx ctx;				/* cpu context */
123 
124 	uint64_t state;				/* current lthread state */
125 
126 	struct lthread_sched *sched;		/* current scheduler */
127 	void *stack;				/* ptr to actual stack */
128 	size_t stack_size;			/* current stack_size */
129 	size_t last_stack_size;			/* last yield  stack_size */
130 	lthread_func_t fun;			/* func ctx is running */
131 	void *arg;				/* func args passed to func */
132 	void *per_lthread_data;			/* per lthread user data */
133 	lthread_exit_func exit_handler;		/* called when thread exits */
134 	uint64_t birth;				/* time lthread was born */
135 	struct lthread_queue *pending_wr_queue;	/* deferred  queue to write */
136 	struct lthread *lt_join;		/* lthread to join on */
137 	uint64_t join;				/* state for joining */
138 	void **lt_exit_ptr;			/* exit ptr for lthread_join */
139 	struct lthread_sched *root_sched;	/* thread was created here*/
140 	struct queue_node *qnode;		/* node when in a queue */
141 	struct rte_timer tim;			/* sleep timer */
142 	struct lthread_tls *tls;		/* keys in use by the thread */
143 	struct lthread_stack *stack_container;	/* stack */
144 	char funcname[MAX_LTHREAD_NAME_SIZE];	/* thread func name */
145 	uint64_t diag_ref;			/* ref to user diag data */
146 } __rte_cache_aligned;
147 
148 #ifdef __cplusplus
149 }
150 #endif
151 
152 #endif				/* LTHREAD_INT_H */
153