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