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 
7a9643ea8Slogwang #ifndef LTHREAD_SCHED_H_
8a9643ea8Slogwang #define LTHREAD_SCHED_H_
9a9643ea8Slogwang 
102bfe3f2eSlogwang #ifdef __cplusplus
112bfe3f2eSlogwang extern "C" {
122bfe3f2eSlogwang #endif
132bfe3f2eSlogwang 
14a9643ea8Slogwang #include "lthread_int.h"
15a9643ea8Slogwang #include "lthread_queue.h"
16a9643ea8Slogwang #include "lthread_objcache.h"
17a9643ea8Slogwang #include "lthread_diag.h"
18a9643ea8Slogwang #include "ctx.h"
19a9643ea8Slogwang 
20a9643ea8Slogwang /*
21a9643ea8Slogwang  * insert an lthread into a queue
22a9643ea8Slogwang  */
23a9643ea8Slogwang static inline void
_ready_queue_insert(struct lthread_sched * sched,struct lthread * lt)24a9643ea8Slogwang _ready_queue_insert(struct lthread_sched *sched, struct lthread *lt)
25a9643ea8Slogwang {
26a9643ea8Slogwang 	if (sched == THIS_SCHED)
27a9643ea8Slogwang 		_lthread_queue_insert_sp((THIS_SCHED)->ready, lt);
28a9643ea8Slogwang 	else
29a9643ea8Slogwang 		_lthread_queue_insert_mp(sched->pready, lt);
30a9643ea8Slogwang }
31a9643ea8Slogwang 
32a9643ea8Slogwang /*
33a9643ea8Slogwang  * remove an lthread from a queue
34a9643ea8Slogwang  */
_ready_queue_remove(struct lthread_queue * q)35a9643ea8Slogwang static inline struct lthread *_ready_queue_remove(struct lthread_queue *q)
36a9643ea8Slogwang {
37a9643ea8Slogwang 	return _lthread_queue_remove(q);
38a9643ea8Slogwang }
39a9643ea8Slogwang 
40a9643ea8Slogwang /**
41a9643ea8Slogwang  * Return true if the ready queue is empty
42a9643ea8Slogwang  */
_ready_queue_empty(struct lthread_queue * q)43a9643ea8Slogwang static inline int _ready_queue_empty(struct lthread_queue *q)
44a9643ea8Slogwang {
45a9643ea8Slogwang 	return _lthread_queue_empty(q);
46a9643ea8Slogwang }
47a9643ea8Slogwang 
_sched_now(void)48a9643ea8Slogwang static inline uint64_t _sched_now(void)
49a9643ea8Slogwang {
50a9643ea8Slogwang 	uint64_t now = rte_rdtsc();
51a9643ea8Slogwang 
52a9643ea8Slogwang 	if (now > (THIS_SCHED)->birth)
53a9643ea8Slogwang 		return now - (THIS_SCHED)->birth;
54a9643ea8Slogwang 	if (now < (THIS_SCHED)->birth)
55a9643ea8Slogwang 		return (THIS_SCHED)->birth - now;
56a9643ea8Slogwang 	/* never return 0 because this means sleep forever */
57a9643ea8Slogwang 	return 1;
58a9643ea8Slogwang }
59a9643ea8Slogwang 
602bfe3f2eSlogwang static __rte_always_inline void
612bfe3f2eSlogwang _affinitize(void);
62a9643ea8Slogwang static inline void
_affinitize(void)63a9643ea8Slogwang _affinitize(void)
64a9643ea8Slogwang {
65a9643ea8Slogwang 	struct lthread *lt = THIS_LTHREAD;
66a9643ea8Slogwang 
67a9643ea8Slogwang 	DIAG_EVENT(lt, LT_DIAG_LTHREAD_SUSPENDED, 0, 0);
68a9643ea8Slogwang 	ctx_switch(&(THIS_SCHED)->ctx, &lt->ctx);
69a9643ea8Slogwang }
70a9643ea8Slogwang 
712bfe3f2eSlogwang static __rte_always_inline void
722bfe3f2eSlogwang _suspend(void);
73a9643ea8Slogwang static inline void
_suspend(void)74a9643ea8Slogwang _suspend(void)
75a9643ea8Slogwang {
76a9643ea8Slogwang 	struct lthread *lt = THIS_LTHREAD;
77a9643ea8Slogwang 
78a9643ea8Slogwang 	(THIS_SCHED)->nb_blocked_threads++;
79a9643ea8Slogwang 	DIAG_EVENT(lt, LT_DIAG_LTHREAD_SUSPENDED, 0, 0);
80a9643ea8Slogwang 	ctx_switch(&(THIS_SCHED)->ctx, &lt->ctx);
81a9643ea8Slogwang 	(THIS_SCHED)->nb_blocked_threads--;
82a9643ea8Slogwang }
83a9643ea8Slogwang 
842bfe3f2eSlogwang static __rte_always_inline void
852bfe3f2eSlogwang _reschedule(void);
86a9643ea8Slogwang static inline void
_reschedule(void)87a9643ea8Slogwang _reschedule(void)
88a9643ea8Slogwang {
89a9643ea8Slogwang 	struct lthread *lt = THIS_LTHREAD;
90a9643ea8Slogwang 
91a9643ea8Slogwang 	DIAG_EVENT(lt, LT_DIAG_LTHREAD_RESCHEDULED, 0, 0);
92a9643ea8Slogwang 	_ready_queue_insert(THIS_SCHED, lt);
93a9643ea8Slogwang 	ctx_switch(&(THIS_SCHED)->ctx, &lt->ctx);
94a9643ea8Slogwang }
95a9643ea8Slogwang 
96a9643ea8Slogwang extern struct lthread_sched *schedcore[];
97a9643ea8Slogwang void _sched_timer_cb(struct rte_timer *tim, void *arg);
98a9643ea8Slogwang void _sched_shutdown(__rte_unused void *arg);
99a9643ea8Slogwang 
1002bfe3f2eSlogwang #ifdef __cplusplus
1012bfe3f2eSlogwang }
1022bfe3f2eSlogwang #endif
103a9643ea8Slogwang 
104a9643ea8Slogwang #endif				/* LTHREAD_SCHED_H_ */
105