source: mainline/uspace/srv/taskman/task.c@ 66b1075

Last change on this file since 66b1075 was 66b1075, checked in by Matthieu Riolo <matthieu.riolo@…>, 5 years ago

improving architecture independency of newly added taskman and sysman

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2009 Martin Decky
3 * Copyright (c) 2009 Jiri Svoboda
4 * Copyright (c) 2015 Michal Koutny
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <assert.h>
32#include <async.h>
33#include <errno.h>
34#include <macros.h>
35#include <malloc.h>
36#include <stdbool.h>
37#include <stdio.h>
38#include <task.h>
39#include <types/task.h>
40
41#include "task.h"
42#include "taskman.h"
43
44typedef struct {
45 task_walker_t walker;
46 void *arg;
47} walker_context_t;
48
49/*
50 * Forwards
51 */
52
53static void task_destroy(task_t **);
54
55/*
56 * Hash table functions
57 */
58
59static size_t ht_task_key_hash(const void *key)
60{
61 return *(task_id_t *)key;
62}
63
64static size_t ht_task_hash(const ht_link_t *item)
65{
66 task_t *ht = hash_table_get_inst(item, task_t, link);
67 return ht->id;
68}
69
70static bool ht_task_key_equal(const void *key, const ht_link_t *item)
71{
72 task_t *ht = hash_table_get_inst(item, task_t, link);
73 return ht->id == *(task_id_t *)key;
74}
75
76/** Perform actions after removal of item from the hash table. */
77static void ht_task_remove(ht_link_t *item)
78{
79 task_t *t = hash_table_get_inst(item, task_t, link);
80 task_destroy(&t);
81}
82
83/** Operations for task hash table. */
84static hash_table_ops_t task_hash_table_ops = {
85 .hash = ht_task_hash,
86 .key_hash = ht_task_key_hash,
87 .key_equal = ht_task_key_equal,
88 .equal = NULL,
89 .remove_callback = ht_task_remove
90};
91
92/** Task hash table structure. */
93static hash_table_t task_hash_table;
94fibril_rwlock_t task_hash_table_lock;
95
96static void task_init(task_t *t)
97{
98 t->exit = TASK_EXIT_RUNNING;
99 t->failed = false;
100 t->retval_type = RVAL_UNSET;
101 t->retval = -1;
102 link_initialize(&t->listeners);
103 t->sess = NULL;
104}
105
106static void task_destroy(task_t **t_ptr)
107{
108 task_t *t = *t_ptr;
109 if (t == NULL) {
110 return;
111 }
112
113 if (t->sess != NULL) {
114 async_hangup(t->sess);
115 }
116 free(t);
117
118 *t_ptr = NULL;
119}
120
121errno_t tasks_init(void)
122{
123 if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) {
124 printf(NAME ": No memory available for tasks\n");
125 return ENOMEM;
126 }
127
128 fibril_rwlock_initialize(&task_hash_table_lock);
129
130 return EOK;
131}
132
133/** Find task by its ID
134 *
135 * Assumes held lock of task_hash_table.
136 *
137 * @param[in] id
138 * @return task structure
139 * @return NULL when no task with given ID exists
140 */
141task_t *task_get_by_id(task_id_t id)
142{
143 ht_link_t *link = hash_table_find(&task_hash_table, &id);
144 if (!link) {
145 return NULL;
146 }
147
148 task_t *t = hash_table_get_inst(link, task_t, link);
149 return t;
150}
151
152static bool internal_walker(ht_link_t *ht_link, void *arg)
153{
154 task_t *t = hash_table_get_inst(ht_link, task_t, link);
155 walker_context_t *ctx = arg;
156 return ctx->walker(t, ctx->arg);
157}
158
159/** Iterate over all tasks
160 *
161 * @note Assumes task_hash_table lock is held.
162 *
163 * @param[in] walker
164 * @param[in] arg generic argument passed to walker function
165 */
166void task_foreach(task_walker_t walker, void *arg)
167{
168 walker_context_t ctx;
169 ctx.walker = walker;
170 ctx.arg = arg;
171
172 hash_table_apply(&task_hash_table, &internal_walker, &ctx);
173}
174
175/** Remove task from our structures
176 *
177 * @note Assumes task_hash_table exclusive lock is held.
178 *
179 * @param[in|out] ptr_t Pointer to task pointer that should be removed, nulls
180 * task pointer.
181 */
182void task_remove(task_t **ptr_t)
183{
184 task_t *t = *ptr_t;
185 if (t == NULL) {
186 return;
187 }
188
189 hash_table_remove_item(&task_hash_table, &t->link);
190 *ptr_t = NULL;
191}
192
193errno_t task_intro(task_id_t id)
194{
195 errno_t rc = EOK;
196
197 fibril_rwlock_write_lock(&task_hash_table_lock);
198
199 task_t *t = task_get_by_id(id);
200 if (t != NULL) {
201 rc = EEXIST;
202 goto finish;
203 }
204
205 t = malloc(sizeof(task_t));
206 if (t == NULL) {
207 rc = ENOMEM;
208 goto finish;
209 }
210
211 /*
212 * Insert into the main table.
213 */
214 task_init(t);
215 t->id = id;
216
217 hash_table_insert(&task_hash_table, &t->link);
218 DPRINTF("%s:%d from %" PRIu64 "\n", __func__, __LINE__, t->id);
219
220finish:
221 fibril_rwlock_write_unlock(&task_hash_table_lock);
222 return rc;
223}
224
225/**
226 * @}
227 */
Note: See TracBrowser for help on using the repository browser.