Changes in / [936835e:aadf01e] in mainline


Ignore:
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/proc/program.h

    r936835e raadf01e  
    4545 * A program is an abstraction of a freshly created (not yet running)
    4646 * userspace task containing a main thread along with its userspace stack.
    47  *
    4847 */
    4948typedef struct program {
    50         struct task *task;           /**< Program task */
    51         struct thread *main_thread;  /**< Program main thread */
     49        struct task *task;              /**< Program task */
     50        struct thread *main_thread;     /**< Program main thread */
    5251} program_t;
    5352
    5453extern void *program_loader;
    5554
    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 *);
     55extern void program_create(as_t *as, uintptr_t entry_addr, char *name,
     56    program_t *p);
     57extern int program_create_from_image(void *image_addr, char *name,
     58    program_t *p);
     59extern int program_create_loader(program_t *p, char *name);
     60extern void program_ready(program_t *p);
    6061
    61 extern unative_t sys_program_spawn_loader(char *, size_t);
     62extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
    6263
    6364#endif
  • kernel/generic/src/proc/program.c

    r936835e raadf01e  
    3434/**
    3535 * @file
    36  * @brief Running userspace programs.
     36 * @brief       Running userspace programs.
    3737 */
    3838
     
    6666/** Create a program using an existing address space.
    6767 *
    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 */
     73void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p)
     74{
     75        as_area_t *a;
    7876        uspace_arg_t *kernel_uarg;
    79        
     77
    8078        kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    8179        kernel_uarg->uspace_entry = (void *) entry_addr;
     
    8583        kernel_uarg->uspace_uarg = NULL;
    8684       
    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
    9188        /*
    92          * Create the data address space area.
     89         * Create the data as_area.
    9390         */
    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,
    9692            LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
    9793            AS_AREA_ATTR_NONE, &anon_backend, NULL);
    98         if (!area)
    99                 return ENOMEM;
    100        
     94
    10195        /*
    10296         * Create the main thread.
    10397         */
    104         prg->main_thread = thread_create(uinit, kernel_uarg, prg->task,
     98        p->main_thread = thread_create(uinit, kernel_uarg, p->task,
    10599            THREAD_FLAG_USPACE, "uinit", false);
    106         if (!prg->main_thread)
    107                 return ELIMIT;
    108        
    109         return EOK;
     100        ASSERT(p->main_thread);
    110101}
    111102
     
    116107 * executable image. The task is returned in *task.
    117108 *
    118  * @param image_addr Address of an executable program image.
    119  * @param name       Name to set for the program's task.
    120  * @param prg        Buffer for storing program info. If image_addr
    121  *                   points to a loader image, p->task will be set to
    122  *                   NULL and EOK will be returned.
     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.
    123114 *
    124115 * @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 */
     117int 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);
    134126        if (rc != EE_OK) {
    135127                as_destroy(as);
    136                 prg->task = NULL;
    137                 prg->main_thread = NULL;
    138                
     128                p->task = NULL;
     129                p->main_thread = NULL;
    139130                if (rc != EE_LOADER)
    140131                        return ENOTSUP;
    141132               
    142133                /* Register image as the program loader */
    143                 if (program_loader != NULL)
    144                         return ELIMIT;
    145                
     134                ASSERT(program_loader == NULL);
    146135                program_loader = image_addr;
    147136                LOG("Registered program loader at 0x%" PRIp "\n",
    148137                    image_addr);
    149                
    150138                return EOK;
    151139        }
    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;
    155144}
    156145
    157146/** Create a task from the program loader image.
    158147 *
    159  * @param prg  Buffer for storing program info.
    160  * @param name Name to set for the program's task.
     148 * @param p     Buffer for storing program info.
     149 * @param name  Name to set for the program's task.
    161150 *
    162151 * @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 */
     153int 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;
    172163        if (!loader) {
    173164                printf("Cannot spawn loader as none was registered\n");
    174165                return ENOENT;
    175166        }
    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);
    179169        if (rc != EE_OK) {
    180170                as_destroy(as);
    181171                return ENOENT;
    182172        }
    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;
    186178}
    187179
     
    190182 * Switch program's main thread to the ready state.
    191183 *
    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 */
     186void program_ready(program_t *p)
     187{
     188        thread_ready(p->main_thread);
    198189}
    199190
     
    203194 * the task name.
    204195 *
    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.
    211200 */
    212201unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
    213202{
     203        program_t p;
     204        int rc;
     205        char namebuf[TASK_NAME_BUFLEN];
     206
    214207        /* Cap length of name and copy it from userspace. */
     208
    215209        if (name_len > TASK_NAME_BUFLEN - 1)
    216210                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);
    220213        if (rc != 0)
    221214                return (unative_t) rc;
    222        
     215
    223216        namebuf[name_len] = 0;
    224        
     217
    225218        /* Spawn the new task. */
    226         program_t prg;
    227         rc = program_create_loader(&prg, namebuf);
     219
     220        rc = program_create_loader(&p, namebuf);
    228221        if (rc != 0)
    229222                return rc;
    230        
     223
    231224        // 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
    235229        return EOK;
    236230}
  • uspace/srv/net/socket/socket_client.c

    r936835e raadf01e  
    580580                fibril_rwlock_write_unlock(&socket_globals.lock);
    581581                fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock);
    582                 // drop the accept lock to avoid deadlock
    583                 fibril_mutex_unlock(&socket->accept_lock);
    584582                fibril_rwlock_write_lock(&socket_globals.lock);
    585                 fibril_mutex_lock(&socket->accept_lock);
    586583        }
    587584        -- socket->blocked;
     
    804801                fibril_rwlock_read_unlock(&socket_globals.lock);
    805802                fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock);
    806                 // drop the receive lock to avoid deadlock
    807                 fibril_mutex_unlock(&socket->receive_lock);
    808803                fibril_rwlock_read_lock(&socket_globals.lock);
    809                 fibril_mutex_lock(&socket->receive_lock);
    810804        }
    811805        -- socket->blocked;
  • uspace/srv/net/tl/icmp/icmp.c

    r936835e raadf01e  
    175175/** Requests an echo message.
    176176 *  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 occurs.
     177 *  Blocks the caller until the reply or the timeout occurres.
    178178 *  @param[in] id The message identifier.
    179179 *  @param[in] sequence The message sequence parameter.
     
    221221
    222222/** 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 fibril
    224  *  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.
    225225 *  Releases the packet.
    226226 *  @param[in] packet The received reply message.
     
    334334        }
    335335
    336         // unlock the globals so that we can wait for the reply
     336        // unlock the globals and wait for a reply
    337337        fibril_rwlock_write_unlock(&icmp_globals.lock);
    338338
     
    340340        icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment);
    341341
    342         // wait for the reply
     342        // wait for a reply
    343343        // timeout in microseconds
    344344        if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){
    345345                result = ERROR_CODE;
     346
     347                // lock the globals again and clean up
     348                fibril_rwlock_write_lock(&icmp_globals.lock);
    346349        }else{
    347350                // read the result
    348351                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        }
    354356
    355357        // destroy the reply structure
     
    634636                // set the result
    635637                reply->result = type;
    636                 // notify the waiting fibril
     638                // notify the main fibril
    637639                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        }
    640644        return EOK;
    641645}
  • uspace/srv/net/tl/udp/udp.c

    r936835e raadf01e  
    418418        struct sockaddr * addr;
    419419        size_t addrlen;
     420        fibril_rwlock_t lock;
    420421        ipc_call_t answer;
    421422        int answer_count;
     
    432433
    433434        socket_cores_initialize(&local_sockets);
     435        fibril_rwlock_initialize(&lock);
    434436
    435437        while(keep_on_going){
     
    451453                                break;
    452454                        case NET_SOCKET:
     455                                fibril_rwlock_write_lock(&lock);
    453456                                *SOCKET_SET_SOCKET_ID(answer) = SOCKET_GET_SOCKET_ID(call);
    454457                                res = socket_create(&local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID(answer));
     458                                fibril_rwlock_write_unlock(&lock);
    455459                                if(res == EOK){
    456460                                        if(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
     
    465469                                res = data_receive((void **) &addr, &addrlen);
    466470                                if(res == EOK){
     471                                        fibril_rwlock_read_lock(&lock);
    467472                                        fibril_rwlock_write_lock(&udp_globals.lock);
    468473                                        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);
    469474                                        fibril_rwlock_write_unlock(&udp_globals.lock);
     475                                        fibril_rwlock_read_unlock(&lock);
    470476                                        free(addr);
    471477                                }
     
    474480                                res = data_receive((void **) &addr, &addrlen);
    475481                                if(res == EOK){
     482                                        fibril_rwlock_read_lock(&lock);
    476483                                        fibril_rwlock_write_lock(&udp_globals.lock);
    477484                                        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));
     
    481488                                                answer_count = 2;
    482489                                        }
     490                                        fibril_rwlock_read_unlock(&lock);
    483491                                        free(addr);
    484492                                }
    485493                                break;
    486494                        case NET_SOCKET_RECVFROM:
     495                                fibril_rwlock_read_lock(&lock);
    487496                                fibril_rwlock_write_lock(&udp_globals.lock);
    488497                                res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
    489498                                fibril_rwlock_write_unlock(&udp_globals.lock);
     499                                fibril_rwlock_read_unlock(&lock);
    490500                                if(res > 0){
    491501                                        *SOCKET_SET_READ_DATA_LENGTH(answer) = res;
     
    496506                                break;
    497507                        case NET_SOCKET_CLOSE:
     508                                fibril_rwlock_write_lock(&lock);
    498509                                fibril_rwlock_write_lock(&udp_globals.lock);
    499510                                res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL);
    500511                                fibril_rwlock_write_unlock(&udp_globals.lock);
     512                                fibril_rwlock_write_unlock(&lock);
    501513                                break;
    502514                        case NET_SOCKET_GETSOCKOPT:
Note: See TracChangeset for help on using the changeset viewer.