Changeset b40bfac in mainline for uspace/lib
- Timestamp:
- 2010-11-08T07:13:25Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63a1e60
- Parents:
- d70a463 (diff), 3da12d74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 7 edited
-
c/generic/fibril_synch.c (modified) (12 diffs)
-
c/generic/task.c (modified) (4 diffs)
-
c/include/ipc/services.h (modified) (1 diff)
-
c/include/task.h (modified) (1 diff)
-
net/adt/module_map.c (modified) (1 diff)
-
net/include/tl_local.h (modified) (1 diff)
-
packet/generic/packet_server.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
rd70a463 rb40bfac 58 58 } 59 59 60 static bool check_for_deadlock(fibril_owner_info_t *oi)61 {62 while (oi && oi->owned_by) {63 if (oi->owned_by == (fibril_t *) fibril_get_id())64 return true;65 oi = oi->owned_by->waits_for;66 }67 68 return false;69 }70 71 60 static void print_deadlock(fibril_owner_info_t *oi) 72 61 { … … 89 78 oi = oi->owned_by->waits_for; 90 79 } 91 92 abort(); 93 } 80 } 81 82 83 static void check_for_deadlock(fibril_owner_info_t *oi) 84 { 85 while (oi && oi->owned_by) { 86 if (oi->owned_by == (fibril_t *) fibril_get_id()) { 87 print_deadlock(oi); 88 abort(); 89 } 90 oi = oi->owned_by->waits_for; 91 } 92 } 93 94 94 95 95 void fibril_mutex_initialize(fibril_mutex_t *fm) … … 113 113 link_initialize(&wdata.wu_event.link); 114 114 list_append(&wdata.wu_event.link, &fm->waiters); 115 116 if (check_for_deadlock(&fm->oi)) 117 print_deadlock(&fm->oi); 115 check_for_deadlock(&fm->oi); 118 116 f->waits_for = &fm->oi; 119 120 117 fibril_switch(FIBRIL_TO_MANAGER); 121 118 } else { … … 183 180 void fibril_rwlock_read_lock(fibril_rwlock_t *frw) 184 181 { 182 fibril_t *f = (fibril_t *) fibril_get_id(); 183 185 184 futex_down(&async_futex); 186 185 if (frw->writers) { 187 fibril_t *f = (fibril_t *) fibril_get_id();188 186 awaiter_t wdata; 189 187 … … 194 192 f->flags &= ~FIBRIL_WRITER; 195 193 list_append(&wdata.wu_event.link, &frw->waiters); 194 check_for_deadlock(&frw->oi); 195 f->waits_for = &frw->oi; 196 196 fibril_switch(FIBRIL_TO_MANAGER); 197 197 } else { 198 frw->readers++; 198 /* Consider the first reader the owner. */ 199 if (frw->readers++ == 0) 200 frw->oi.owned_by = f; 199 201 futex_up(&async_futex); 200 202 } … … 203 205 void fibril_rwlock_write_lock(fibril_rwlock_t *frw) 204 206 { 207 fibril_t *f = (fibril_t *) fibril_get_id(); 208 205 209 futex_down(&async_futex); 206 210 if (frw->writers || frw->readers) { 207 fibril_t *f = (fibril_t *) fibril_get_id();208 211 awaiter_t wdata; 209 212 … … 214 217 f->flags |= FIBRIL_WRITER; 215 218 list_append(&wdata.wu_event.link, &frw->waiters); 219 check_for_deadlock(&frw->oi); 220 f->waits_for = &frw->oi; 216 221 fibril_switch(FIBRIL_TO_MANAGER); 217 222 } else { 223 frw->oi.owned_by = f; 218 224 frw->writers++; 219 225 futex_up(&async_futex); … … 226 232 assert(frw->readers || (frw->writers == 1)); 227 233 if (frw->readers) { 228 if (--frw->readers) 234 if (--frw->readers) { 235 if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) { 236 /* 237 * If this reader firbril was considered the 238 * owner of this rwlock, clear the ownership 239 * information even if there are still more 240 * readers. 241 * 242 * This is the limitation of the detection 243 * mechanism rooted in the fact that tracking 244 * all readers would require dynamically 245 * allocated memory for keeping linkage info. 246 */ 247 frw->oi.owned_by = NULL; 248 } 229 249 goto out; 250 } 230 251 } else { 231 252 frw->writers--; … … 233 254 234 255 assert(!frw->readers && !frw->writers); 256 257 frw->oi.owned_by = NULL; 235 258 236 259 while (!list_empty(&frw->waiters)) { … … 241 264 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 242 265 f = (fibril_t *) wdp->fid; 266 267 f->waits_for = NULL; 243 268 244 269 if (f->flags & FIBRIL_WRITER) { … … 250 275 fibril_add_ready(wdp->fid); 251 276 frw->writers++; 277 frw->oi.owned_by = f; 252 278 optimize_execution_power(); 253 279 break; … … 257 283 list_remove(&wdp->wu_event.link); 258 284 fibril_add_ready(wdp->fid); 259 frw->readers++; 285 if (frw->readers++ == 0) { 286 /* Consider the first reader the owner. */ 287 frw->oi.owned_by = f; 288 } 260 289 optimize_execution_power(); 261 290 } -
uspace/lib/c/generic/task.c
rd70a463 rb40bfac 39 39 #include <errno.h> 40 40 #include <loader/loader.h> 41 #include <stdarg.h> 41 42 #include <str.h> 42 43 #include <ipc/ns.h> … … 68 69 * 69 70 * This is really just a convenience wrapper over the more complicated 70 * loader API. 71 * 72 * @param path Pathname of the binary to execute. 73 * @param argv Command-line arguments. 74 * @param err If not NULL, the error value is stored here. 75 * 76 * @return ID of the newly created task or zero on error. 77 * 78 */ 79 task_id_t task_spawn(const char *path, const char *const args[], int *err) 80 { 71 * loader API. Arguments are passed as a null-terminated array of strings. 72 * 73 * @param id If not NULL, the ID of the task is stored here on success. 74 * @param path Pathname of the binary to execute. 75 * @param argv Command-line arguments. 76 * 77 * @return Zero on success or negative error code. 78 */ 79 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 80 { 81 loader_t *ldr; 82 task_id_t task_id; 83 int rc; 84 81 85 /* Connect to a program loader. */ 82 loader_t *ldr = loader_connect(); 83 if (ldr == NULL) { 84 if (err != NULL) 85 *err = EREFUSED; 86 87 return 0; 88 } 86 ldr = loader_connect(); 87 if (ldr == NULL) 88 return EREFUSED; 89 89 90 90 /* Get task ID. */ 91 task_id_t task_id; 92 int rc = loader_get_task_id(ldr, &task_id); 91 rc = loader_get_task_id(ldr, &task_id); 93 92 if (rc != EOK) 94 93 goto error; … … 149 148 free(ldr); 150 149 151 if ( err!= NULL)152 * err = EOK;153 154 return task_id;150 if (id != NULL) 151 *id = task_id; 152 153 return EOK; 155 154 156 155 error: … … 158 157 loader_abort(ldr); 159 158 free(ldr); 160 161 if (err != NULL) 162 *err = rc; 163 164 return 0; 159 return rc; 160 } 161 162 /** Create a new task by running an executable from the filesystem. 163 * 164 * This is really just a convenience wrapper over the more complicated 165 * loader API. Arguments are passed as a null-terminated list of arguments. 166 * 167 * @param id If not NULL, the ID of the task is stored here on success. 168 * @param path Pathname of the binary to execute. 169 * @param ... Command-line arguments. 170 * 171 * @return Zero on success or negative error code. 172 */ 173 int task_spawnl(task_id_t *task_id, const char *path, ...) 174 { 175 va_list ap; 176 int rc, cnt; 177 const char *arg; 178 const char **arglist; 179 180 /* Count the number of arguments. */ 181 cnt = 0; 182 va_start(ap, path); 183 do { 184 arg = va_arg(ap, const char *); 185 cnt++; 186 } while (arg != NULL); 187 va_end(ap); 188 189 /* Allocate argument list. */ 190 arglist = malloc(cnt * sizeof(const char *)); 191 if (arglist == NULL) 192 return ENOMEM; 193 194 /* Fill in arguments. */ 195 cnt = 0; 196 va_start(ap, path); 197 do { 198 arg = va_arg(ap, const char *); 199 arglist[cnt++] = arg; 200 } while (arg != NULL); 201 va_end(ap); 202 203 /* Spawn task. */ 204 rc = task_spawnv(task_id, path, arglist); 205 206 /* Free argument list. */ 207 free(arglist); 208 return rc; 165 209 } 166 210 -
uspace/lib/c/include/ipc/services.h
rd70a463 rb40bfac 39 39 40 40 typedef enum { 41 SERVICE_LOAD = 1, 41 SERVICE_NONE = 0, 42 SERVICE_LOAD, 42 43 SERVICE_PCI, 43 44 SERVICE_VIDEO, -
uspace/lib/c/include/task.h
rd70a463 rb40bfac 48 48 extern int task_set_name(const char *); 49 49 extern task_id_t task_spawn(const char *, const char *const[], int *); 50 extern int task_spawnv(task_id_t *, const char *path, const char *const []); 51 extern int task_spawnl(task_id_t *, const char *path, ...); 52 50 53 extern int task_wait(task_id_t id, task_exit_t *, int *); 51 54 extern int task_retval(int); -
uspace/lib/net/adt/module_map.c
rd70a463 rb40bfac 132 132 task_id_t spawn(const char *fname) 133 133 { 134 const char *argv[2];135 task_id_t res;134 task_id_t id; 135 int rc; 136 136 137 argv[0] = fname;138 argv[1] = NULL;139 res = task_spawn(fname, argv, NULL);137 rc = task_spawnl(&id, fname, fname, NULL); 138 if (rc != EOK) 139 return 0; 140 140 141 return res;141 return id; 142 142 } 143 143 -
uspace/lib/net/include/tl_local.h
rd70a463 rb40bfac 37 37 #include <async.h> 38 38 39 /** Starts the TL module. 40 * 41 * Initializes the client connection serving function, initializes the module, 42 * registers the module service and starts the async manager, processing IPC 43 * messages in an infinite loop. 44 * 45 * @param[in] client_connection The client connection processing function. The 46 * module skeleton propagates its own one. 47 * @returns EOK on successful module termination. 48 * @returns Other error codes as defined for the module initialize 49 * function. 50 * @returns Other error codes as defined for the REGISTER_ME() macro 51 * function. 52 */ 39 53 extern int tl_module_message_standalone(ipc_callid_t, ipc_call_t *, 40 54 ipc_call_t *, int *); 55 56 57 /** Processes the TL module message. 58 * 59 * @param[in] callid The message identifier. 60 * @param[in] call The message parameters. 61 * @param[out] answer The message answer parameters. 62 * @param[out] answer_count The last parameter for the actual answer in the 63 * answer parameter. 64 * @returns EOK on success. 65 * @returns Other error codes as defined for the module's message 66 * standalone function. 67 */ 41 68 extern int tl_module_start_standalone(async_client_conn_t); 42 69 -
uspace/lib/packet/generic/packet_server.c
rd70a463 rb40bfac 212 212 213 213 for (index = 0; index < FREE_QUEUES_COUNT; index++) { 214 if (length > ps_globals.sizes[index]) 214 if ((length > ps_globals.sizes[index]) && 215 (index < FREE_QUEUES_COUNT - 1)) 215 216 continue; 216 217
Note:
See TracChangeset
for help on using the changeset viewer.
