1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (c) 2022 Collabora Ltd.
3bf215546Sopenharmony_ci * Copyright © 2014 Intel Corporation
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22bf215546Sopenharmony_ci * IN THE SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci * Authors:
25bf215546Sopenharmony_ci *    Jason Ekstrand (jason@jlekstrand.net)
26bf215546Sopenharmony_ci *
27bf215546Sopenharmony_ci */
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "u_worklist.h"
30bf215546Sopenharmony_ci#include "ralloc.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_civoid
33bf215546Sopenharmony_ciu_worklist_init(u_worklist *w, unsigned num_entries, void *mem_ctx)
34bf215546Sopenharmony_ci{
35bf215546Sopenharmony_ci   w->size = num_entries;
36bf215546Sopenharmony_ci   w->count = 0;
37bf215546Sopenharmony_ci   w->start = 0;
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci   w->present = rzalloc_array(mem_ctx, BITSET_WORD, BITSET_WORDS(num_entries));
40bf215546Sopenharmony_ci   w->entries = rzalloc_array(mem_ctx, unsigned *, num_entries);
41bf215546Sopenharmony_ci}
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_civoid
44bf215546Sopenharmony_ciu_worklist_fini(u_worklist *w)
45bf215546Sopenharmony_ci{
46bf215546Sopenharmony_ci   ralloc_free(w->present);
47bf215546Sopenharmony_ci   ralloc_free(w->entries);
48bf215546Sopenharmony_ci}
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_civoid
51bf215546Sopenharmony_ciu_worklist_push_head_index(u_worklist *w, unsigned *index)
52bf215546Sopenharmony_ci{
53bf215546Sopenharmony_ci   /* Pushing a block we already have is a no-op */
54bf215546Sopenharmony_ci   if (BITSET_TEST(w->present, *index))
55bf215546Sopenharmony_ci      return;
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci   assert(w->count < w->size);
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   if (w->start == 0)
60bf215546Sopenharmony_ci      w->start = w->size - 1;
61bf215546Sopenharmony_ci   else
62bf215546Sopenharmony_ci      w->start--;
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci   w->count++;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   w->entries[w->start] = index;
67bf215546Sopenharmony_ci   BITSET_SET(w->present, *index);
68bf215546Sopenharmony_ci}
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ciunsigned *
71bf215546Sopenharmony_ciu_worklist_peek_head_index(const u_worklist *w)
72bf215546Sopenharmony_ci{
73bf215546Sopenharmony_ci   assert(w->count > 0);
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   return w->entries[w->start];
76bf215546Sopenharmony_ci}
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ciunsigned *
79bf215546Sopenharmony_ciu_worklist_pop_head_index(u_worklist *w)
80bf215546Sopenharmony_ci{
81bf215546Sopenharmony_ci   assert(w->count > 0);
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   unsigned head = w->start;
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   w->start = (w->start + 1) % w->size;
86bf215546Sopenharmony_ci   w->count--;
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   BITSET_CLEAR(w->present, *(w->entries[head]));
89bf215546Sopenharmony_ci   return w->entries[head];
90bf215546Sopenharmony_ci}
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_civoid
93bf215546Sopenharmony_ciu_worklist_push_tail_index(u_worklist *w, unsigned *index)
94bf215546Sopenharmony_ci{
95bf215546Sopenharmony_ci   /* Pushing a block we already have is a no-op */
96bf215546Sopenharmony_ci   if (BITSET_TEST(w->present, *index))
97bf215546Sopenharmony_ci      return;
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   assert(w->count < w->size);
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   w->count++;
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci   unsigned tail = (w->start + w->count - 1) % w->size;
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   w->entries[tail] = index;
106bf215546Sopenharmony_ci   BITSET_SET(w->present, *index);
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ciunsigned *
110bf215546Sopenharmony_ciu_worklist_peek_tail_index(const u_worklist *w)
111bf215546Sopenharmony_ci{
112bf215546Sopenharmony_ci   assert(w->count > 0);
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci   unsigned tail = (w->start + w->count - 1) % w->size;
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   return w->entries[tail];
117bf215546Sopenharmony_ci}
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ciunsigned *
120bf215546Sopenharmony_ciu_worklist_pop_tail_index(u_worklist *w)
121bf215546Sopenharmony_ci{
122bf215546Sopenharmony_ci   assert(w->count > 0);
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   unsigned tail = (w->start + w->count - 1) % w->size;
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   w->count--;
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   BITSET_CLEAR(w->present, *(w->entries[tail]));
129bf215546Sopenharmony_ci   return w->entries[tail];
130bf215546Sopenharmony_ci}
131