Changes in / [936835e:aadf01e] in mainline
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/proc/program.h
r936835e raadf01e 45 45 * A program is an abstraction of a freshly created (not yet running) 46 46 * userspace task containing a main thread along with its userspace stack. 47 *48 47 */ 49 48 typedef struct program { 50 struct task *task; 51 struct thread *main_thread; 49 struct task *task; /**< Program task */ 50 struct thread *main_thread; /**< Program main thread */ 52 51 } program_t; 53 52 54 53 extern void *program_loader; 55 54 56 extern int program_create(as_t *, uintptr_t, char *, program_t *); 57 extern int program_create_from_image(void *, char *, program_t *); 58 extern int program_create_loader(program_t *, char *); 59 extern void program_ready(program_t *); 55 extern void program_create(as_t *as, uintptr_t entry_addr, char *name, 56 program_t *p); 57 extern int program_create_from_image(void *image_addr, char *name, 58 program_t *p); 59 extern int program_create_loader(program_t *p, char *name); 60 extern void program_ready(program_t *p); 60 61 61 extern unative_t sys_program_spawn_loader(char * , size_t);62 extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len); 62 63 63 64 #endif -
kernel/generic/src/proc/program.c
r936835e raadf01e 34 34 /** 35 35 * @file 36 * @brief 36 * @brief Running userspace programs. 37 37 */ 38 38 … … 66 66 /** Create a program using an existing address space. 67 67 * 68 * @param as Address space containing a binary program image. 69 * @param entry_addr Program entry-point address in program address space. 70 * @param name Name to set for the program's task. 71 * @param prg Buffer for storing program information. 72 * 73 * @return EOK on success or negative error code. 74 * 75 */ 76 int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg) 77 { 68 * @param as Address space containing a binary program image. 69 * @param entry_addr Program entry-point address in program address space. 70 * @param name Name to set for the program's task. 71 * @param p Buffer for storing program information. 72 */ 73 void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p) 74 { 75 as_area_t *a; 78 76 uspace_arg_t *kernel_uarg; 79 77 80 78 kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); 81 79 kernel_uarg->uspace_entry = (void *) entry_addr; … … 85 83 kernel_uarg->uspace_uarg = NULL; 86 84 87 prg->task = task_create(as, name); 88 if (!prg->task) 89 return ELIMIT; 90 85 p->task = task_create(as, name); 86 ASSERT(p->task); 87 91 88 /* 92 * Create the data a ddress spacearea.89 * Create the data as_area. 93 90 */ 94 as_area_t *area = as_area_create(as, 95 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, 91 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, 96 92 LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, 97 93 AS_AREA_ATTR_NONE, &anon_backend, NULL); 98 if (!area) 99 return ENOMEM; 100 94 101 95 /* 102 96 * Create the main thread. 103 97 */ 104 p rg->main_thread = thread_create(uinit, kernel_uarg, prg->task,98 p->main_thread = thread_create(uinit, kernel_uarg, p->task, 105 99 THREAD_FLAG_USPACE, "uinit", false); 106 if (!prg->main_thread) 107 return ELIMIT; 108 109 return EOK; 100 ASSERT(p->main_thread); 110 101 } 111 102 … … 116 107 * executable image. The task is returned in *task. 117 108 * 118 * @param image_addr 119 * @param name 120 * @param p rgBuffer for storing program info. If image_addr121 * 122 * 109 * @param image_addr Address of an executable program image. 110 * @param name Name to set for the program's task. 111 * @param p Buffer for storing program info. If image_addr 112 * points to a loader image, p->task will be set to 113 * NULL and EOK will be returned. 123 114 * 124 115 * @return EOK on success or negative error code. 125 * 126 */ 127 int program_create_from_image(void *image_addr, char *name, program_t *prg) 128 { 129 as_t *as = as_create(0); 130 if (!as) 131 return ENOMEM; 132 133 unsigned int rc = elf_load((elf_header_t *) image_addr, as, 0); 116 */ 117 int program_create_from_image(void *image_addr, char *name, program_t *p) 118 { 119 as_t *as; 120 unsigned int rc; 121 122 as = as_create(0); 123 ASSERT(as); 124 125 rc = elf_load((elf_header_t *) image_addr, as, 0); 134 126 if (rc != EE_OK) { 135 127 as_destroy(as); 136 prg->task = NULL; 137 prg->main_thread = NULL; 138 128 p->task = NULL; 129 p->main_thread = NULL; 139 130 if (rc != EE_LOADER) 140 131 return ENOTSUP; 141 132 142 133 /* Register image as the program loader */ 143 if (program_loader != NULL) 144 return ELIMIT; 145 134 ASSERT(program_loader == NULL); 146 135 program_loader = image_addr; 147 136 LOG("Registered program loader at 0x%" PRIp "\n", 148 137 image_addr); 149 150 138 return EOK; 151 139 } 152 153 return program_create(as, ((elf_header_t *) image_addr)->e_entry, 154 name, prg); 140 141 program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p); 142 143 return EOK; 155 144 } 156 145 157 146 /** Create a task from the program loader image. 158 147 * 159 * @param p rgBuffer for storing program info.160 * @param name 148 * @param p Buffer for storing program info. 149 * @param name Name to set for the program's task. 161 150 * 162 151 * @return EOK on success or negative error code. 163 * 164 */ 165 int program_create_loader(program_t *prg, char *name) 166 { 167 as_t *as = as_create(0); 168 if (!as) 169 return ENOMEM; 170 171 void *loader = program_loader; 152 */ 153 int program_create_loader(program_t *p, char *name) 154 { 155 as_t *as; 156 unsigned int rc; 157 void *loader; 158 159 as = as_create(0); 160 ASSERT(as); 161 162 loader = program_loader; 172 163 if (!loader) { 173 164 printf("Cannot spawn loader as none was registered\n"); 174 165 return ENOENT; 175 166 } 176 177 unsigned int rc = elf_load((elf_header_t *) program_loader, as, 178 ELD_F_LOADER); 167 168 rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); 179 169 if (rc != EE_OK) { 180 170 as_destroy(as); 181 171 return ENOENT; 182 172 } 183 184 return program_create(as, ((elf_header_t *) program_loader)->e_entry, 185 name, prg); 173 174 program_create(as, ((elf_header_t *) program_loader)->e_entry, 175 name, p); 176 177 return EOK; 186 178 } 187 179 … … 190 182 * Switch program's main thread to the ready state. 191 183 * 192 * @param prg Program to make ready. 193 * 194 */ 195 void program_ready(program_t *prg) 196 { 197 thread_ready(prg->main_thread); 184 * @param p Program to make ready. 185 */ 186 void program_ready(program_t *p) 187 { 188 thread_ready(p->main_thread); 198 189 } 199 190 … … 203 194 * the task name. 204 195 * 205 * @param uspace_name Name to set on the new task (typically the same 206 * as the command used to execute it). 207 * @param name_len Length of the name. 208 * 209 * @return EOK on success or an error code from @ref errno.h. 210 * 196 * @param name Name to set on the new task (typically the same 197 * as the command used to execute it). 198 * 199 * @return 0 on success or an error code from @ref errno.h. 211 200 */ 212 201 unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len) 213 202 { 203 program_t p; 204 int rc; 205 char namebuf[TASK_NAME_BUFLEN]; 206 214 207 /* Cap length of name and copy it from userspace. */ 208 215 209 if (name_len > TASK_NAME_BUFLEN - 1) 216 210 name_len = TASK_NAME_BUFLEN - 1; 217 218 char namebuf[TASK_NAME_BUFLEN]; 219 int rc = copy_from_uspace(namebuf, uspace_name, name_len); 211 212 rc = copy_from_uspace(namebuf, uspace_name, name_len); 220 213 if (rc != 0) 221 214 return (unative_t) rc; 222 215 223 216 namebuf[name_len] = 0; 224 217 225 218 /* Spawn the new task. */ 226 program_t prg; 227 rc = program_create_loader(&p rg, namebuf);219 220 rc = program_create_loader(&p, namebuf); 228 221 if (rc != 0) 229 222 return rc; 230 223 231 224 // FIXME: control the capabilities 232 cap_set(prg.task, cap_get(TASK)); 233 program_ready(&prg); 234 225 cap_set(p.task, cap_get(TASK)); 226 227 program_ready(&p); 228 235 229 return EOK; 236 230 } -
uspace/srv/net/socket/socket_client.c
r936835e raadf01e 580 580 fibril_rwlock_write_unlock(&socket_globals.lock); 581 581 fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock); 582 // drop the accept lock to avoid deadlock583 fibril_mutex_unlock(&socket->accept_lock);584 582 fibril_rwlock_write_lock(&socket_globals.lock); 585 fibril_mutex_lock(&socket->accept_lock);586 583 } 587 584 -- socket->blocked; … … 804 801 fibril_rwlock_read_unlock(&socket_globals.lock); 805 802 fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock); 806 // drop the receive lock to avoid deadlock807 fibril_mutex_unlock(&socket->receive_lock);808 803 fibril_rwlock_read_lock(&socket_globals.lock); 809 fibril_mutex_lock(&socket->receive_lock);810 804 } 811 805 -- socket->blocked; -
uspace/srv/net/tl/icmp/icmp.c
r936835e raadf01e 175 175 /** Requests an echo message. 176 176 * Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout. 177 * Blocks the caller until the reply or the timeout occur s.177 * Blocks the caller until the reply or the timeout occurres. 178 178 * @param[in] id The message identifier. 179 179 * @param[in] sequence The message sequence parameter. … … 221 221 222 222 /** Tries to set the pending reply result as the received message type. 223 * If the reply data is not present, the reply timed out and the other fibril224 * is already awake.223 * If the reply data are still present, the reply timeouted and the parent fibril is awaken. 224 * The global lock is not released in this case to be reused by the parent fibril. 225 225 * Releases the packet. 226 226 * @param[in] packet The received reply message. … … 334 334 } 335 335 336 // unlock the globals so that we can wait for thereply336 // unlock the globals and wait for a reply 337 337 fibril_rwlock_write_unlock(&icmp_globals.lock); 338 338 … … 340 340 icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment); 341 341 342 // wait for thereply342 // wait for a reply 343 343 // timeout in microseconds 344 344 if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){ 345 345 result = ERROR_CODE; 346 347 // lock the globals again and clean up 348 fibril_rwlock_write_lock(&icmp_globals.lock); 346 349 }else{ 347 350 // read the result 348 351 result = reply->result; 349 } 350 351 // drop the reply mutex before locking the globals again 352 fibril_mutex_unlock(&reply->mutex); 353 fibril_rwlock_write_lock(&icmp_globals.lock); 352 353 // release the reply structure 354 fibril_mutex_unlock(&reply->mutex); 355 } 354 356 355 357 // destroy the reply structure … … 634 636 // set the result 635 637 reply->result = type; 636 // notify the waitingfibril638 // notify the main fibril 637 639 fibril_condvar_signal(&reply->condvar); 638 } 639 fibril_rwlock_write_unlock(&icmp_globals.lock); 640 }else{ 641 // unlock only if no reply 642 fibril_rwlock_write_unlock(&icmp_globals.lock); 643 } 640 644 return EOK; 641 645 } -
uspace/srv/net/tl/udp/udp.c
r936835e raadf01e 418 418 struct sockaddr * addr; 419 419 size_t addrlen; 420 fibril_rwlock_t lock; 420 421 ipc_call_t answer; 421 422 int answer_count; … … 432 433 433 434 socket_cores_initialize(&local_sockets); 435 fibril_rwlock_initialize(&lock); 434 436 435 437 while(keep_on_going){ … … 451 453 break; 452 454 case NET_SOCKET: 455 fibril_rwlock_write_lock(&lock); 453 456 *SOCKET_SET_SOCKET_ID(answer) = SOCKET_GET_SOCKET_ID(call); 454 457 res = socket_create(&local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID(answer)); 458 fibril_rwlock_write_unlock(&lock); 455 459 if(res == EOK){ 456 460 if(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){ … … 465 469 res = data_receive((void **) &addr, &addrlen); 466 470 if(res == EOK){ 471 fibril_rwlock_read_lock(&lock); 467 472 fibril_rwlock_write_lock(&udp_globals.lock); 468 473 res = socket_bind(&local_sockets, &udp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port); 469 474 fibril_rwlock_write_unlock(&udp_globals.lock); 475 fibril_rwlock_read_unlock(&lock); 470 476 free(addr); 471 477 } … … 474 480 res = data_receive((void **) &addr, &addrlen); 475 481 if(res == EOK){ 482 fibril_rwlock_read_lock(&lock); 476 483 fibril_rwlock_write_lock(&udp_globals.lock); 477 484 res = udp_sendto_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS(call), SOCKET_SET_DATA_FRAGMENT_SIZE(answer), SOCKET_GET_FLAGS(call)); … … 481 488 answer_count = 2; 482 489 } 490 fibril_rwlock_read_unlock(&lock); 483 491 free(addr); 484 492 } 485 493 break; 486 494 case NET_SOCKET_RECVFROM: 495 fibril_rwlock_read_lock(&lock); 487 496 fibril_rwlock_write_lock(&udp_globals.lock); 488 497 res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen); 489 498 fibril_rwlock_write_unlock(&udp_globals.lock); 499 fibril_rwlock_read_unlock(&lock); 490 500 if(res > 0){ 491 501 *SOCKET_SET_READ_DATA_LENGTH(answer) = res; … … 496 506 break; 497 507 case NET_SOCKET_CLOSE: 508 fibril_rwlock_write_lock(&lock); 498 509 fibril_rwlock_write_lock(&udp_globals.lock); 499 510 res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL); 500 511 fibril_rwlock_write_unlock(&udp_globals.lock); 512 fibril_rwlock_write_unlock(&lock); 501 513 break; 502 514 case NET_SOCKET_GETSOCKOPT:
Note:
See TracChangeset
for help on using the changeset viewer.