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
RevLine 
[1be7bee]1/*
[c675ab1]2 * Copyright (c) 2009 Martin Decky
3 * Copyright (c) 2009 Jiri Svoboda
4 * Copyright (c) 2015 Michal Koutny
5 * All rights reserved.
[1be7bee]6 *
[c675ab1]7 * Redistribution and use in source and binary forms, with or without
[1be7bee]8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
[c675ab1]11 * - Redistributions of source code must retain the above copyright
[1be7bee]12 * notice, this list of conditions and the following disclaimer.
[c675ab1]13 * - Redistributions in binary form must reproduce the above copyright
[1be7bee]14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
[c675ab1]16 * - The name of the author may not be used to endorse or promote products
[1be7bee]17 * derived from this software without specific prior written permission.
18 *
[c675ab1]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.
[1be7bee]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>
[2f44fafd]38#include <task.h>
[1be7bee]39#include <types/task.h>
40
41#include "task.h"
42#include "taskman.h"
43
[4667b5c]44typedef struct {
45 task_walker_t walker;
46 void *arg;
47} walker_context_t;
[102f641]48
[4667b5c]49/*
50 * Forwards
51 */
52
53static void task_destroy(task_t **);
54
55/*
56 * Hash table functions
57 */
58
[241f1985]59static size_t ht_task_key_hash(const void *key)
[1be7bee]60{
[102f641]61 return *(task_id_t *)key;
[1be7bee]62}
63
[4667b5c]64static size_t ht_task_hash(const ht_link_t *item)
[1be7bee]65{
[035d7d8]66 task_t *ht = hash_table_get_inst(item, task_t, link);
[1be7bee]67 return ht->id;
68}
69
[241f1985]70static bool ht_task_key_equal(const void *key, const ht_link_t *item)
[1be7bee]71{
[035d7d8]72 task_t *ht = hash_table_get_inst(item, task_t, link);
[102f641]73 return ht->id == *(task_id_t *)key;
[1be7bee]74}
75
[c675ab1]76/** Perform actions after removal of item from the hash table. */
[4667b5c]77static void ht_task_remove(ht_link_t *item)
[1be7bee]78{
[4667b5c]79 task_t *t = hash_table_get_inst(item, task_t, link);
80 task_destroy(&t);
[1be7bee]81}
82
[c675ab1]83/** Operations for task hash table. */
[1be7bee]84static hash_table_ops_t task_hash_table_ops = {
[4667b5c]85 .hash = ht_task_hash,
86 .key_hash = ht_task_key_hash,
87 .key_equal = ht_task_key_equal,
[1be7bee]88 .equal = NULL,
[4667b5c]89 .remove_callback = ht_task_remove
[1be7bee]90};
91
92/** Task hash table structure. */
[4667b5c]93static hash_table_t task_hash_table;
[035d7d8]94fibril_rwlock_t task_hash_table_lock;
[1be7bee]95
[4667b5c]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
[25697163]121errno_t tasks_init(void)
[1be7bee]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 }
[035d7d8]127
128 fibril_rwlock_initialize(&task_hash_table_lock);
[102f641]129
[1be7bee]130 return EOK;
131}
132
[035d7d8]133/** Find task by its ID
134 *
135 * Assumes held lock of task_hash_table.
[2f44fafd]136 *
[035d7d8]137 * @param[in] id
138 * @return task structure
139 * @return NULL when no task with given ID exists
[2f44fafd]140 */
[035d7d8]141task_t *task_get_by_id(task_id_t id)
[1be7bee]142{
143 ht_link_t *link = hash_table_find(&task_hash_table, &id);
[035d7d8]144 if (!link) {
145 return NULL;
[1be7bee]146 }
[102f641]147
[035d7d8]148 task_t *t = hash_table_get_inst(link, task_t, link);
149 return t;
[1be7bee]150}
151
[4667b5c]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
[25697163]193errno_t task_intro(task_id_t id)
[1be7bee]194{
[25697163]195 errno_t rc = EOK;
[2f44fafd]196
197 fibril_rwlock_write_lock(&task_hash_table_lock);
198
[012dd8e]199 task_t *t = task_get_by_id(id);
[035d7d8]200 if (t != NULL) {
[241f1985]201 rc = EEXIST;
[2f44fafd]202 goto finish;
203 }
[102f641]204
[035d7d8]205 t = malloc(sizeof(task_t));
206 if (t == NULL) {
[2f44fafd]207 rc = ENOMEM;
208 goto finish;
209 }
[62273d1]210
[1be7bee]211 /*
212 * Insert into the main table.
213 */
[4667b5c]214 task_init(t);
[012dd8e]215 t->id = id;
[035d7d8]216
217 hash_table_insert(&task_hash_table, &t->link);
[66b1075]218 DPRINTF("%s:%d from %" PRIu64 "\n", __func__, __LINE__, t->id);
[102f641]219
[2f44fafd]220finish:
221 fibril_rwlock_write_unlock(&task_hash_table_lock);
222 return rc;
[1be7bee]223}
224
225/**
226 * @}
227 */
Note: See TracBrowser for help on using the repository browser.