Changeset 4667b5c in mainline for uspace/srv/taskman/task.c
- Timestamp:
- 2019-08-07T11:10:46Z (6 years ago)
- Children:
- bb57a00
- Parents:
- 130ba46
- git-author:
- Michal Koutný <xm.koutny+hos@…> (2015-11-13 01:56:10)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-07 11:10:46)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/taskman/task.c
r130ba46 r4667b5c 42 42 #include "taskman.h" 43 43 44 static size_t task_key_hash(void *key) 44 typedef struct { 45 task_walker_t walker; 46 void *arg; 47 } walker_context_t; 48 49 /* 50 * Forwards 51 */ 52 53 static void task_destroy(task_t **); 54 55 /* 56 * Hash table functions 57 */ 58 59 static size_t ht_task_key_hash(void *key) 45 60 { 46 61 return *(task_id_t*)key; 47 62 } 48 63 49 static size_t task_hash(const ht_link_t *item)64 static size_t ht_task_hash(const ht_link_t *item) 50 65 { 51 66 task_t *ht = hash_table_get_inst(item, task_t, link); … … 53 68 } 54 69 55 static bool task_key_equal(void *key, const ht_link_t *item)70 static bool ht_task_key_equal(void *key, const ht_link_t *item) 56 71 { 57 72 task_t *ht = hash_table_get_inst(item, task_t, link); … … 60 75 61 76 /** Perform actions after removal of item from the hash table. */ 62 static void task_remove(ht_link_t *item) 63 { 64 free(hash_table_get_inst(item, task_t, link)); 77 static 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); 65 81 } 66 82 67 83 /** Operations for task hash table. */ 68 84 static hash_table_ops_t task_hash_table_ops = { 69 .hash = task_hash,70 .key_hash = task_key_hash,71 .key_equal = task_key_equal,85 .hash = ht_task_hash, 86 .key_hash = ht_task_key_hash, 87 .key_equal = ht_task_key_equal, 72 88 .equal = NULL, 73 .remove_callback = task_remove89 .remove_callback = ht_task_remove 74 90 }; 75 91 76 92 /** Task hash table structure. */ 77 hash_table_t task_hash_table;93 static hash_table_t task_hash_table; 78 94 fibril_rwlock_t task_hash_table_lock; 79 95 80 int task_init(void) 81 { 82 if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) { 83 printf(NAME ": No memory available for tasks\n"); 84 return ENOMEM; 85 } 86 87 fibril_rwlock_initialize(&task_hash_table_lock); 88 89 return EOK; 90 } 91 92 /** Find task by its ID 93 * 94 * Assumes held lock of task_hash_table. 95 * 96 * @param[in] id 97 * @return task structure 98 * @return NULL when no task with given ID exists 99 */ 100 task_t *task_get_by_id(task_id_t id) 101 { 102 ht_link_t *link = hash_table_find(&task_hash_table, &id); 103 if (!link) { 104 return NULL; 105 } 106 107 task_t *t = hash_table_get_inst(link, task_t, link); 108 return t; 109 } 110 111 int task_intro(task_id_t id) 112 { 113 int rc = EOK; 114 115 fibril_rwlock_write_lock(&task_hash_table_lock); 116 117 task_t *t = task_get_by_id(id); 118 if (t != NULL) { 119 rc = EEXISTS; 120 goto finish; 121 } 122 123 t = malloc(sizeof(task_t)); 124 if (t == NULL) { 125 rc = ENOMEM; 126 goto finish; 127 } 128 129 /* 130 * Insert into the main table. 131 */ 132 t->id = id; 96 static void task_init(task_t *t) 97 { 133 98 t->exit = TASK_EXIT_RUNNING; 134 99 t->failed = false; … … 137 102 link_initialize(&t->listeners); 138 103 t->sess = NULL; 104 } 105 106 static 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 121 int 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 */ 141 task_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 152 static 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 */ 166 void 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 */ 182 void 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 193 int task_intro(task_id_t id) 194 { 195 int 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 = EEXISTS; 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; 139 216 140 217 hash_table_insert(&task_hash_table, &t->link); 141 printf("%s: %llu\n", __func__, t->id);218 DPRINTF("%s: %llu\n", __func__, t->id); 142 219 143 220 finish:
Note:
See TracChangeset
for help on using the changeset viewer.