@@ -17,7 +17,7 @@ u64 scx_atq_create_internal(bool fifo, size_t capacity)
1717 if (!atq )
1818 return (u64 )NULL ;
1919
20- atq -> tree = rb_create ();
20+ atq -> tree = rb_create (RB_NOALLOC , RB_DUPLICATE );
2121 if (!atq -> tree )
2222 return (u64 )NULL ;
2323
@@ -28,102 +28,105 @@ u64 scx_atq_create_internal(bool fifo, size_t capacity)
2828 return (u64 )atq ;
2929}
3030
31- __hidden
32- int scx_atq_insert (scx_atq_t * atq , u64 taskc_ptr )
31+ __hidden __inline
32+ int scx_atq_insert_vtime_unlocked (scx_atq_t __arg_arena * atq , scx_task_common __arg_arena * taskc , u64 vtime )
3333{
34- rbnode_t * node ;
34+ rbnode_t * node = & taskc -> node ;
3535 int ret ;
3636
37- if (! atq -> fifo )
38- return - EINVAL ;
37+ if (unlikely ( atq -> size == atq -> capacity ) )
38+ return - ENOSPC ;
3939
40- /*
41- * Use dummy sequence number because we're
42- * outside of the critical section.
43- */
44- node = rb_node_alloc (atq -> tree , 0 , taskc_ptr );
45- if (!node )
46- return - ENOMEM ;
47-
48- ret = arena_spin_lock (& atq -> lock );
49- if (ret ) {
50- rb_node_free (atq -> tree , node );
51- return ret ;
52- }
53-
54- if (unlikely (atq -> size == atq -> capacity )) {
55- ret = - ENOSPC ;
56- goto error ;
57- }
40+ if ((vtime == SCX_ATQ_FIFO ) != atq -> fifo )
41+ return - EINVAL ;
5842
5943 /*
60- * "Leak" the seq on error. We only want
44+ * For FIFO, "Leak" the seq on error. We only want
6145 * sequence numbers to be monotonic, not
6246 * consecutive.
6347 */
64- node -> key = atq -> seq ++ ;
48+ node -> key = (vtime == SCX_ATQ_FIFO ) ? atq -> seq ++ : vtime ;
49+ node -> value = (u64 )taskc ;
6550
66- ret = rb_insert_node (atq -> tree , node , RB_DUPLICATE );
51+ ret = rb_insert_node (atq -> tree , node );
6752 if (ret )
68- goto error ;
53+ return ret ;
6954
55+ taskc -> atq = atq ;
7056 atq -> size += 1 ;
7157
72- arena_spin_unlock (& atq -> lock );
73-
7458 return 0 ;
59+ }
60+
61+ /*
62+ * XXXETSAL: We are using the __hidden antipattern for API functions because some
63+ * older kernels do not allow function calls with preemption disabled. We will replace
64+ * these annotations with the proper ones (__weak) at some point in the future.
65+ */
66+
67+ __hidden
68+ int scx_atq_insert_vtime (scx_atq_t __arg_arena * atq , scx_task_common __arg_arena * taskc , u64 vtime )
69+ {
70+ int ret ;
71+
72+ ret = arena_spin_lock (& atq -> lock );
73+ if (ret )
74+ return ret ;
75+
76+ ret = scx_atq_insert_vtime_unlocked (atq , taskc , vtime );
7577
76- error :
7778 arena_spin_unlock (& atq -> lock );
78- rb_node_free (atq -> tree , node );
7979
8080 return ret ;
8181}
8282
8383__hidden
84- int scx_atq_insert_vtime (scx_atq_t * atq , u64 taskc_ptr , u64 vtime )
84+ int scx_atq_insert_unlocked (scx_atq_t * atq , scx_task_common __arg_arena * taskc )
8585{
86- rbnode_t * node ;
87- int ret ;
86+ return scx_atq_insert_vtime_unlocked ( atq , taskc , SCX_ATQ_FIFO ) ;
87+ }
8888
89- if (atq -> fifo )
90- return - EINVAL ;
89+ __hidden
90+ int scx_atq_insert (scx_atq_t * atq , scx_task_common __arg_arena * taskc )
91+ {
92+ return scx_atq_insert_vtime (atq , taskc , SCX_ATQ_FIFO );
93+ }
9194
92- node = rb_node_alloc (atq -> tree , vtime , taskc_ptr );
93- if (!node )
94- return - ENOMEM ;
95+ __hidden
96+ int scx_atq_remove_unlocked (scx_atq_t * atq , scx_task_common __arg_arena * taskc )
97+ {
98+ int ret ;
9599
96- ret = arena_spin_lock (& atq -> lock );
97- if (ret ) {
98- rb_node_free (atq -> tree , node );
99- return ret ;
100- }
100+ /* Are we in this ATQ in the first place? */
101+ if (taskc -> atq != atq )
102+ return - EINVAL ;
101103
102- if (unlikely (atq -> size == atq -> capacity )) {
103- ret = - ENOSPC ;
104- goto error ;
105- }
104+ ret = rb_remove_node (atq -> tree , & taskc -> node );
105+ taskc -> atq = NULL ;
106106
107- ret = rb_insert_node (atq -> tree , node , RB_DUPLICATE );
108- if (ret )
109- goto error ;
107+ return ret ;
108+ }
110109
111- atq -> size += 1 ;
110+ __hidden
111+ int scx_atq_remove (scx_atq_t * atq , scx_task_common __arg_arena * taskc )
112+ {
113+ int ret ;
112114
113- arena_spin_unlock (& atq -> lock );
115+ ret = arena_spin_lock (& atq -> lock );
116+ if (ret )
117+ return ret ;
114118
115- return 0 ;
119+ ret = scx_atq_remove_unlocked ( atq , taskc ) ;
116120
117- error :
118- arena_spin_unlock (& atq -> lock );
119- rb_node_free (atq -> tree , node );
121+ arena_spin_unlock (& atq -> lock );
120122
121- return ret ;
123+ return ret ;
122124}
123125
124126__hidden
125127u64 scx_atq_pop (scx_atq_t * atq )
126128{
129+ scx_task_common * taskc ;
127130 u64 vtime , taskc_ptr ;
128131 int ret ;
129132
@@ -140,6 +143,9 @@ u64 scx_atq_pop(scx_atq_t *atq)
140143 if (!ret )
141144 atq -> size -= 1 ;
142145
146+ taskc = (scx_task_common * )taskc_ptr ;
147+ taskc -> atq = NULL ;
148+
143149 arena_spin_unlock (& atq -> lock );
144150
145151 if (ret ) {
0 commit comments