Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 936835e in mainline


Ignore:
Timestamp:
2010-03-07T15:35:32Z (12 years ago)
Author:
Lukas Mejdrech <lukasmejdrech@…>
Branches:
lfn, master
Children:
836dd794
Parents:
aadf01e (diff), b5cbff4 (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.
Message:

Merge mainline changes, revision 311

Files:
5 edited

Legend:

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

    raadf01e r936835e  
    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 *
    4748 */
    4849typedef struct program {
    49         struct task *task;              /**< Program task */
    50         struct thread *main_thread;     /**< Program main thread */
     50        struct task *task;           /**< Program task */
     51        struct thread *main_thread;  /**< Program main thread */
    5152} program_t;
    5253
    5354extern void *program_loader;
    5455
    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);
     56extern int program_create(as_t *, uintptr_t, char *, program_t *);
     57extern int program_create_from_image(void *, char *, program_t *);
     58extern int program_create_loader(program_t *, char *);
     59extern void program_ready(program_t *);
    6160
    62 extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
     61extern unative_t sys_program_spawn_loader(char *, size_t);
    6362
    6463#endif
  • kernel/generic/src/proc/program.c

    raadf01e r936835e  
    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 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;
     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 */
     76int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg)
     77{
    7678        uspace_arg_t *kernel_uarg;
    77 
     79       
    7880        kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    7981        kernel_uarg->uspace_entry = (void *) entry_addr;
     
    8385        kernel_uarg->uspace_uarg = NULL;
    8486       
    85         p->task = task_create(as, name);
    86         ASSERT(p->task);
    87 
     87        prg->task = task_create(as, name);
     88        if (!prg->task)
     89                return ELIMIT;
     90       
    8891        /*
    89          * Create the data as_area.
     92         * Create the data address space area.
    9093         */
    91         a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
     94        as_area_t *area = as_area_create(as,
     95            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
    9296            LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
    9397            AS_AREA_ATTR_NONE, &anon_backend, NULL);
    94 
     98        if (!area)
     99                return ENOMEM;
     100       
    95101        /*
    96102         * Create the main thread.
    97103         */
    98         p->main_thread = thread_create(uinit, kernel_uarg, p->task,
     104        prg->main_thread = thread_create(uinit, kernel_uarg, prg->task,
    99105            THREAD_FLAG_USPACE, "uinit", false);
    100         ASSERT(p->main_thread);
     106        if (!prg->main_thread)
     107                return ELIMIT;
     108       
     109        return EOK;
    101110}
    102111
     
    107116 * executable image. The task is returned in *task.
    108117 *
    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.
     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.
    114123 *
    115124 * @return EOK on success or negative error code.
    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);
     125 *
     126 */
     127int 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);
    126134        if (rc != EE_OK) {
    127135                as_destroy(as);
    128                 p->task = NULL;
    129                 p->main_thread = NULL;
     136                prg->task = NULL;
     137                prg->main_thread = NULL;
     138               
    130139                if (rc != EE_LOADER)
    131140                        return ENOTSUP;
    132141               
    133142                /* Register image as the program loader */
    134                 ASSERT(program_loader == NULL);
     143                if (program_loader != NULL)
     144                        return ELIMIT;
     145               
    135146                program_loader = image_addr;
    136147                LOG("Registered program loader at 0x%" PRIp "\n",
    137148                    image_addr);
     149               
    138150                return EOK;
    139151        }
    140 
    141         program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p);
    142 
    143         return EOK;
     152       
     153        return program_create(as, ((elf_header_t *) image_addr)->e_entry,
     154            name, prg);
    144155}
    145156
    146157/** Create a task from the program loader image.
    147158 *
    148  * @param p     Buffer for storing program info.
    149  * @param name  Name to set for the program's task.
     159 * @param prg  Buffer for storing program info.
     160 * @param name Name to set for the program's task.
    150161 *
    151162 * @return EOK on success or negative error code.
    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;
     163 *
     164 */
     165int 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;
    163172        if (!loader) {
    164173                printf("Cannot spawn loader as none was registered\n");
    165174                return ENOENT;
    166175        }
    167 
    168         rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER);
     176       
     177        unsigned int rc = elf_load((elf_header_t *) program_loader, as,
     178            ELD_F_LOADER);
    169179        if (rc != EE_OK) {
    170180                as_destroy(as);
    171181                return ENOENT;
    172182        }
    173 
    174         program_create(as, ((elf_header_t *) program_loader)->e_entry,
    175             name, p);
    176 
    177         return EOK;
     183       
     184        return program_create(as, ((elf_header_t *) program_loader)->e_entry,
     185            name, prg);
    178186}
    179187
     
    182190 * Switch program's main thread to the ready state.
    183191 *
    184  * @param p Program to make ready.
    185  */
    186 void program_ready(program_t *p)
    187 {
    188         thread_ready(p->main_thread);
     192 * @param prg Program to make ready.
     193 *
     194 */
     195void program_ready(program_t *prg)
     196{
     197        thread_ready(prg->main_thread);
    189198}
    190199
     
    194203 * the task name.
    195204 *
    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.
     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 *
    200211 */
    201212unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
    202213{
    203         program_t p;
    204         int rc;
    205         char namebuf[TASK_NAME_BUFLEN];
    206 
    207214        /* Cap length of name and copy it from userspace. */
    208 
    209215        if (name_len > TASK_NAME_BUFLEN - 1)
    210216                name_len = TASK_NAME_BUFLEN - 1;
    211 
    212         rc = copy_from_uspace(namebuf, uspace_name, name_len);
     217       
     218        char namebuf[TASK_NAME_BUFLEN];
     219        int rc = copy_from_uspace(namebuf, uspace_name, name_len);
    213220        if (rc != 0)
    214221                return (unative_t) rc;
    215 
     222       
    216223        namebuf[name_len] = 0;
    217 
     224       
    218225        /* Spawn the new task. */
    219 
    220         rc = program_create_loader(&p, namebuf);
     226        program_t prg;
     227        rc = program_create_loader(&prg, namebuf);
    221228        if (rc != 0)
    222229                return rc;
    223 
     230       
    224231        // FIXME: control the capabilities
    225         cap_set(p.task, cap_get(TASK));
    226 
    227         program_ready(&p);
    228 
     232        cap_set(prg.task, cap_get(TASK));
     233        program_ready(&prg);
     234       
    229235        return EOK;
    230236}
  • uspace/srv/net/socket/socket_client.c

    raadf01e r936835e  
    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);
    582584                fibril_rwlock_write_lock(&socket_globals.lock);
     585                fibril_mutex_lock(&socket->accept_lock);
    583586        }
    584587        -- socket->blocked;
     
    801804                fibril_rwlock_read_unlock(&socket_globals.lock);
    802805                fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock);
     806                // drop the receive lock to avoid deadlock
     807                fibril_mutex_unlock(&socket->receive_lock);
    803808                fibril_rwlock_read_lock(&socket_globals.lock);
     809                fibril_mutex_lock(&socket->receive_lock);
    804810        }
    805811        -- socket->blocked;
  • uspace/srv/net/tl/icmp/icmp.c

    raadf01e r936835e  
    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 occurres.
     177 *  Blocks the caller until the reply or the timeout occurs.
    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 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.
     223 *  If the reply data is not present, the reply timed out and the other fibril
     224 *  is already awake.
    225225 *  Releases the packet.
    226226 *  @param[in] packet The received reply message.
     
    334334        }
    335335
    336         // unlock the globals and wait for a reply
     336        // unlock the globals so that we can wait for the 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 a reply
     342        // wait for the 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);
    349346        }else{
    350347                // read the result
    351348                result = reply->result;
    352 
    353                 // release the reply structure
    354                 fibril_mutex_unlock(&reply->mutex);
    355         }
     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);
    356354
    357355        // destroy the reply structure
     
    636634                // set the result
    637635                reply->result = type;
    638                 // notify the main fibril
     636                // notify the waiting fibril
    639637                fibril_condvar_signal(&reply->condvar);
    640         }else{
    641                 // unlock only if no reply
    642                 fibril_rwlock_write_unlock(&icmp_globals.lock);
    643         }
     638        }
     639        fibril_rwlock_write_unlock(&icmp_globals.lock);
    644640        return EOK;
    645641}
  • uspace/srv/net/tl/udp/udp.c

    raadf01e r936835e  
    418418        struct sockaddr * addr;
    419419        size_t addrlen;
    420         fibril_rwlock_t lock;
    421420        ipc_call_t answer;
    422421        int answer_count;
     
    433432
    434433        socket_cores_initialize(&local_sockets);
    435         fibril_rwlock_initialize(&lock);
    436434
    437435        while(keep_on_going){
     
    453451                                break;
    454452                        case NET_SOCKET:
    455                                 fibril_rwlock_write_lock(&lock);
    456453                                *SOCKET_SET_SOCKET_ID(answer) = SOCKET_GET_SOCKET_ID(call);
    457454                                res = socket_create(&local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID(answer));
    458                                 fibril_rwlock_write_unlock(&lock);
    459455                                if(res == EOK){
    460456                                        if(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
     
    469465                                res = data_receive((void **) &addr, &addrlen);
    470466                                if(res == EOK){
    471                                         fibril_rwlock_read_lock(&lock);
    472467                                        fibril_rwlock_write_lock(&udp_globals.lock);
    473468                                        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);
    474469                                        fibril_rwlock_write_unlock(&udp_globals.lock);
    475                                         fibril_rwlock_read_unlock(&lock);
    476470                                        free(addr);
    477471                                }
     
    480474                                res = data_receive((void **) &addr, &addrlen);
    481475                                if(res == EOK){
    482                                         fibril_rwlock_read_lock(&lock);
    483476                                        fibril_rwlock_write_lock(&udp_globals.lock);
    484477                                        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));
     
    488481                                                answer_count = 2;
    489482                                        }
    490                                         fibril_rwlock_read_unlock(&lock);
    491483                                        free(addr);
    492484                                }
    493485                                break;
    494486                        case NET_SOCKET_RECVFROM:
    495                                 fibril_rwlock_read_lock(&lock);
    496487                                fibril_rwlock_write_lock(&udp_globals.lock);
    497488                                res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
    498489                                fibril_rwlock_write_unlock(&udp_globals.lock);
    499                                 fibril_rwlock_read_unlock(&lock);
    500490                                if(res > 0){
    501491                                        *SOCKET_SET_READ_DATA_LENGTH(answer) = res;
     
    506496                                break;
    507497                        case NET_SOCKET_CLOSE:
    508                                 fibril_rwlock_write_lock(&lock);
    509498                                fibril_rwlock_write_lock(&udp_globals.lock);
    510499                                res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL);
    511500                                fibril_rwlock_write_unlock(&udp_globals.lock);
    512                                 fibril_rwlock_write_unlock(&lock);
    513501                                break;
    514502                        case NET_SOCKET_GETSOCKOPT:
Note: See TracChangeset for help on using the changeset viewer.