source: mainline/kernel/generic/include/adt/list.h@ 8ccd2ea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8ccd2ea was ea7890e7, checked in by Jakub Jermar <jakub@…>, 18 years ago

More efficient and simpler task termination.

Based on the assumption, that after its creation, only the task itself can create more threads for itself,
the last thread with userspace context to execute thread_exit() will perform futex and IPC cleanup. When
the task has no threads, it is destroyed. Both the cleanup and destruction is controlled by reference
counting.

As for userspace threads, even though there could be a global garbage collector for joining threads, it is
much simpler if the uinit thread detaches itself before switching to userspace.

task_kill() is now an idempotent operation. It just instructs the threads within a task to exit.

Change in the name of a thread state: Undead → JoinMe.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup genericadt
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_LIST_H_
36#define KERN_LIST_H_
37
38#include <arch/types.h>
39
40/** Doubly linked list head and link type. */
41typedef struct link {
42 struct link *prev; /**< Pointer to the previous item in the list. */
43 struct link *next; /**< Pointer to the next item in the list. */
44} link_t;
45
46/** Declare and initialize statically allocated list.
47 *
48 * @param name Name of the new statically allocated list.
49 */
50#define LIST_INITIALIZE(name) \
51 link_t name = { .prev = &name, .next = &name }
52
53/** Initialize doubly-linked circular list link
54 *
55 * Initialize doubly-linked list link.
56 *
57 * @param link Pointer to link_t structure to be initialized.
58 */
59static inline void link_initialize(link_t *link)
60{
61 link->prev = NULL;
62 link->next = NULL;
63}
64
65/** Initialize doubly-linked circular list
66 *
67 * Initialize doubly-linked circular list.
68 *
69 * @param head Pointer to link_t structure representing head of the list.
70 */
71static inline void list_initialize(link_t *head)
72{
73 head->prev = head;
74 head->next = head;
75}
76
77/** Add item to the beginning of doubly-linked circular list
78 *
79 * Add item to the beginning of doubly-linked circular list.
80 *
81 * @param link Pointer to link_t structure to be added.
82 * @param head Pointer to link_t structure representing head of the list.
83 */
84static inline void list_prepend(link_t *link, link_t *head)
85{
86 link->next = head->next;
87 link->prev = head;
88 head->next->prev = link;
89 head->next = link;
90}
91
92/** Add item to the end of doubly-linked circular list
93 *
94 * Add item to the end of doubly-linked circular list.
95 *
96 * @param link Pointer to link_t structure to be added.
97 * @param head Pointer to link_t structure representing head of the list.
98 */
99static inline void list_append(link_t *link, link_t *head)
100{
101 link->prev = head->prev;
102 link->next = head;
103 head->prev->next = link;
104 head->prev = link;
105}
106
107/** Remove item from doubly-linked circular list
108 *
109 * Remove item from doubly-linked circular list.
110 *
111 * @param link Pointer to link_t structure to be removed from the list it is
112 * contained in.
113 */
114static inline void list_remove(link_t *link)
115{
116 link->next->prev = link->prev;
117 link->prev->next = link->next;
118 link_initialize(link);
119}
120
121/** Query emptiness of doubly-linked circular list
122 *
123 * Query emptiness of doubly-linked circular list.
124 *
125 * @param head Pointer to link_t structure representing head of the list.
126 */
127static inline bool list_empty(link_t *head)
128{
129 return head->next == head ? true : false;
130}
131
132
133/** Split or concatenate headless doubly-linked circular list
134 *
135 * Split or concatenate headless doubly-linked circular list.
136 *
137 * Note that the algorithm works both directions:
138 * concatenates splitted lists and splits concatenated lists.
139 *
140 * @param part1 Pointer to link_t structure leading the first (half of the
141 * headless) list.
142 * @param part2 Pointer to link_t structure leading the second (half of the
143 * headless) list.
144 */
145static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
146{
147 link_t *hlp;
148
149 part1->prev->next = part2;
150 part2->prev->next = part1;
151 hlp = part1->prev;
152 part1->prev = part2->prev;
153 part2->prev = hlp;
154}
155
156
157/** Split headless doubly-linked circular list
158 *
159 * Split headless doubly-linked circular list.
160 *
161 * @param part1 Pointer to link_t structure leading the first half of the
162 * headless list.
163 * @param part2 Pointer to link_t structure leading the second half of the
164 * headless list.
165 */
166static inline void headless_list_split(link_t *part1, link_t *part2)
167{
168 headless_list_split_or_concat(part1, part2);
169}
170
171/** Concatenate two headless doubly-linked circular lists
172 *
173 * Concatenate two headless doubly-linked circular lists.
174 *
175 * @param part1 Pointer to link_t structure leading the first headless list.
176 * @param part2 Pointer to link_t structure leading the second headless list.
177 */
178static inline void headless_list_concat(link_t *part1, link_t *part2)
179{
180 headless_list_split_or_concat(part1, part2);
181}
182
183#define list_get_instance(link, type, member) \
184 ((type *)(((uint8_t *)(link)) - ((uint8_t *)&(((type *)NULL)->member))))
185
186extern bool list_member(const link_t *link, const link_t *head);
187extern void list_concat(link_t *head1, link_t *head2);
188
189#endif
190
191/** @}
192 */
Note: See TracBrowser for help on using the repository browser.