Changeset 0a8f070 in mainline


Ignore:
Timestamp:
2019-08-07T02:33:03Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
fe86d9d
Parents:
103939e
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-08-16 16:04:14)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 02:33:03)
Message:

Create taskman server (extracts task-related operations from naming service)

  • Exploits initial phones connected to spawn parent instead of NS.
  • session_ns changed to session_primary (setup during taskman-loader handshake).
  • Task creation moved from NS to taskman (no clonable services anymore).
  • Other task-related operations implementation is to come (task_retval is temporarily dummy).
  • Async framework: implicit connections — create fibrils for calls that arrived through initial phone.

Conflicts:

abi/include/abi/ipc/methods.h
boot/Makefile.common
uspace/Makefile
uspace/app/trace/ipcp.c
uspace/lib/c/generic/async.c
uspace/lib/c/generic/libc.c
uspace/lib/c/generic/loader.c
uspace/lib/c/generic/ns.c
uspace/lib/c/generic/private/async.h
uspace/lib/c/generic/private/ns.h
uspace/lib/c/generic/task.c
uspace/lib/c/include/async.h
uspace/lib/c/include/ipc/services.h
uspace/lib/c/include/ipc/taskman.h
uspace/lib/c/include/loader/pcb.h
uspace/lib/c/include/ns.h
uspace/srv/loader/main.c
uspace/srv/ns/clonable.c
uspace/srv/ns/ns.c

Files:
4 added
1 deleted
20 edited
1 moved

Legend:

Unmodified
Added
Removed
  • abi/include/abi/ipc/methods.h

    r103939e r0a8f070  
    3939
    4040/* Well known phone descriptors */
    41 static cap_phone_handle_t const PHONE_NS = (cap_phone_handle_t) (CAP_NIL + 1);
     41static cap_phone_handle_t const PHONE_INITIAL = (cap_phone_handle_t) (CAP_NIL + 1);
    4242
    4343/** Kernel IPC interfaces
  • boot/Makefile.common

    r103939e r0a8f070  
    7676        $(USPACE_PATH)/srv/bd/rd/rd \
    7777        $(USPACE_PATH)/srv/vfs/vfs \
    78         $(USPACE_PATH)/srv/logger/logger
     78        $(USPACE_PATH)/srv/logger/logger \
     79        $(USPACE_PATH)/srv/taskman/taskman
    7980
    8081ifeq ($(RDFMT),tmpfs)
  • uspace/Makefile

    r103939e r0a8f070  
    120120        srv/taskmon \
    121121        srv/sysman \
     122        srv/taskman \
    122123        srv/vfs \
    123124        srv/bd/sata_bd \
  • uspace/app/trace/ipcp.c

    r103939e r0a8f070  
    302302        }
    303303
    304         if ((phone == PHONE_NS) && (method == IPC_M_CONNECT_ME_TO) &&
     304        // TODO obsoleted (initial phone needn't to be phone to NS anymore)
     305        //      actually what connections should it monitor?
     306        if ((phone == PHONE_INITIAL) && (method == IPC_M_CONNECT_ME_TO) &&
    305307            (retval == 0)) {
    306308                /* Connected to a service (through NS) */
  • uspace/lib/c/Makefile

    r103939e r0a8f070  
    165165        generic/arg_parse.c \
    166166        generic/stats.c \
     167        generic/taskman.c \
    167168        generic/assert.c \
    168169        generic/bsearch.c \
  • uspace/lib/c/generic/async/client.c

    r103939e r0a8f070  
    124124static fibril_rmutex_t message_mutex;
    125125
    126 /** Naming service session */
    127 async_sess_t session_ns;
     126/** Primary session (spawn parent, later naming service) */
     127async_sess_t *session_primary = NULL;
    128128
    129129/** Message data */
     
    168168static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
    169169
     170
     171static async_sess_t *create_session_primary(void)
     172{
     173        async_sess_t *session = (async_sess_t *) malloc(sizeof(async_sess_t));
     174
     175        if (session != NULL) {
     176                session_ns->iface = 0;
     177                session->mgmt = EXCHANGE_ATOMIC;
     178                session->phone = PHONE_INITIAL;
     179                session->arg1 = 0;
     180                session->arg2 = 0;
     181                session->arg3 = 0;
     182               
     183                fibril_mutex_initialize(&session->remote_state_mtx);
     184                session->remote_state_data = NULL;
     185               
     186                list_initialize(&session->exch_list);
     187                fibril_mutex_initialize(&session->mutex);
     188                atomic_set(&session->refcnt, 0);
     189                &session.exchanges = 0;
     190        }
     191
     192        return session;
     193}
     194
     195
    170196/** Initialize the async framework.
    171197 *
    172198 */
    173 void __async_client_init(void)
     199void __async_client_init(async_sess_t *session)
    174200{
    175201        if (fibril_rmutex_initialize(&message_mutex) != EOK)
    176202                abort();
    177203
    178         session_ns.iface = 0;
    179         session_ns.mgmt = EXCHANGE_ATOMIC;
    180         session_ns.phone = PHONE_NS;
    181         session_ns.arg1 = 0;
    182         session_ns.arg2 = 0;
    183         session_ns.arg3 = 0;
    184 
    185         fibril_mutex_initialize(&session_ns.remote_state_mtx);
    186         session_ns.remote_state_data = NULL;
    187 
    188         list_initialize(&session_ns.exch_list);
    189         fibril_mutex_initialize(&session_ns.mutex);
    190         session_ns.exchanges = 0;
     204        if (session == NULL) {
     205                session_primary = create_session_primary();
     206        } else {
     207                session_primary = session;
     208        }
     209
     210        if (session_primary == NULL)
     211                abort();
    191212}
    192213
     
    807828        *out_phone = (cap_phone_handle_t) ipc_get_arg5(&result);
    808829        return EOK;
     830}
     831
     832/** Injects another session instead of original primary session
     833 *
     834 * @param  session  Session to naming service.
     835 *
     836 * @return old primary session (to spawn parent)
     837 */
     838async_sess_t *async_session_primary_swap(async_sess_t *session)
     839{
     840        assert(session_primary->phone == PHONE_INITIAL);
     841
     842        async_sess_t *old_primary = session_primary;
     843        session_primary = session;
     844        return old_primary;
    809845}
    810846
  • uspace/lib/c/generic/async/server.c

    r103939e r0a8f070  
    216216}
    217217
     218static async_client_conn_t implicit_connection = NULL;
    218219static fibril_rmutex_t client_mutex;
    219220static hash_table_t client_hash_table;
     
    964965        /* Route the call according to its request label */
    965966        errno_t rc = route_call(call);
    966         if (rc == EOK)
     967        if (rc == EOK) {
    967968                return;
     969        } else if (implicit_connection != NULL) {
     970                async_new_connection(call->in_task_id, call->in_phone_hash,
     971                    callid, call, implicit_connection, NULL);
     972                return;
     973        }
    968974
    969975        // TODO: Log the error.
  • uspace/lib/c/generic/libc.c

    r103939e r0a8f070  
    103103        }
    104104#endif
    105 
     105       
     106        /* Setup async framework */
    106107        __async_server_init();
    107         __async_client_init();
     108        if (__pcb == NULL) {
     109                __async_client_init(NULL);
     110        } else {
     111                __async_client_init(__pcb->session_primary);
     112        }
    108113        __async_ports_init();
    109114
  • uspace/lib/c/generic/loader.c

    r103939e r0a8f070  
    3333 */
    3434
     35#include <async.h>
     36#include <errno.h>
    3537#include <ipc/loader.h>
    3638#include <ipc/services.h>
     39#include <ipc/taskman.h>
     40#include <libc.h>
     41#include <loader/loader.h>
    3742#include <ns.h>
    38 #include <libc.h>
     43#include <stdlib.h>
     44#include <str.h>
    3945#include <task.h>
    40 #include <str.h>
    41 #include <stdlib.h>
    42 #include <async.h>
    43 #include <errno.h>
    4446#include <vfs/vfs.h>
    45 #include <loader/loader.h>
    4647#include "private/loader.h"
    4748
     
    6768
    6869        async_sess_t *sess =
    69             service_connect_blocking(SERVICE_LOADER, INTERFACE_LOADER, 0);
     70            service_connect_blocking(SERVICE_TASKMAN, TASKMAN_CONNECT_TO_LOADER, 0);
    7071        if (sess == NULL) {
    7172                free(ldr);
  • uspace/lib/c/generic/ns.c

    r103939e r0a8f070  
    4141
    4242/*
    43  * XXX ns does not know about session_ns, so we create an extra session for
     43 * XXX ns does not know about session_primary, so we create an extra session for
    4444 * actual communicaton
    4545 */
    46 static async_sess_t *sess_ns = NULL;
     46static async_sess_t *sess_primary = NULL;
    4747
    4848errno_t service_register(service_t service, iface_t iface,
    4949    async_port_handler_t handler, void *data)
    5050{
    51         async_sess_t *sess = ns_session_get();
     51        async_sess_t *sess = get_session_primary();
    5252        if (sess == NULL)
    5353                return EIO;
     
    8181        async_set_fallback_port_handler(handler, data);
    8282
    83         async_sess_t *sess = ns_session_get();
     83        async_sess_t *sess = get_session_primary();
    8484        if (sess == NULL)
    8585                return EIO;
     
    105105async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3)
    106106{
    107         async_sess_t *sess = ns_session_get();
     107        async_sess_t *sess = get_session_primary();
    108108        if (sess == NULL)
    109109                return NULL;
     
    133133    sysarg_t arg3)
    134134{
    135         async_sess_t *sess = ns_session_get();
     135        async_sess_t *sess = get_session_primary();
    136136        if (sess == NULL)
    137137                return NULL;
     
    157157errno_t ns_ping(void)
    158158{
    159         async_sess_t *sess = ns_session_get();
     159        async_sess_t *sess = get_session_primary();
    160160        if (sess == NULL)
    161161                return EIO;
     
    168168}
    169169
    170 errno_t ns_intro(task_id_t id)
    171 {
    172         async_exch_t *exch;
    173         async_sess_t *sess = ns_session_get();
    174         if (sess == NULL)
    175                 return EIO;
    176170
    177         exch = async_exchange_begin(sess);
    178         errno_t rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
    179         async_exchange_end(exch);
    180 
    181         return rc;
    182 }
    183 
    184 async_sess_t *ns_session_get(void)
     171async_sess_t *get_session_primary(void)
    185172{
    186173        async_exch_t *exch;
    187174
    188         if (sess_ns == NULL) {
    189                 exch = async_exchange_begin(&session_ns);
    190                 sess_ns = async_connect_me_to(exch, 0, 0, 0);
     175        if (sess_primary == NULL) {
     176                exch = async_exchange_begin(&session_primary);
     177                sess_primary = async_connect_me_to(exch, 0, 0, 0);
    191178                async_exchange_end(exch);
    192                 if (sess_ns == NULL)
     179                if (sess_primary == NULL)
    193180                        return NULL;
    194181        }
    195182
    196         return sess_ns;
     183        return sess_primary;
    197184}
    198185
  • uspace/lib/c/generic/private/async.h

    r103939e r0a8f070  
    9696extern void __async_server_init(void);
    9797extern void __async_server_fini(void);
    98 extern void __async_client_init(void);
     98extern void __async_client_init(async_sess_t *);
    9999extern void __async_client_fini(void);
    100100extern void __async_ports_init(void);
  • uspace/lib/c/generic/private/ns.h

    r103939e r0a8f070  
    3838#include <async.h>
    3939
    40 extern async_sess_t session_ns;
     40extern async_sess_t *session_primary;
    4141
    4242#endif
  • uspace/lib/c/generic/task.c

    r103939e r0a8f070  
    325325errno_t task_setup_wait(task_id_t id, task_wait_t *wait)
    326326{
    327         async_sess_t *sess_ns = ns_session_get();
     327        async_sess_t *sess_ns = get_session_primary();
    328328        if (sess_ns == NULL)
    329329                return EIO;
    330330
    331331        async_exch_t *exch = async_exchange_begin(sess_ns);
     332
    332333        wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id),
    333334            &wait->result);
     
    407408errno_t task_retval(int val)
    408409{
    409         async_sess_t *sess_ns = ns_session_get();
     410        async_sess_t *sess_ns = get_session_primary();
    410411        if (sess_ns == NULL)
    411412                return EIO;
  • uspace/lib/c/include/async.h

    r103939e r0a8f070  
    131131extern void *async_get_client_data_by_id(task_id_t);
    132132extern void async_put_client_data_by_id(task_id_t);
     133
     134extern void async_set_implicit_connection(async_client_conn_t);
    133135
    134136extern errno_t async_create_port(iface_t, async_port_handler_t, void *,
     
    274276extern sysarg_t async_get_label(void);
    275277
     278extern async_sess_t *async_session_primary_swap(async_sess_t *);
    276279extern async_sess_t *async_connect_me_to(async_exch_t *, iface_t, sysarg_t,
    277280    sysarg_t);
  • uspace/lib/c/include/ipc/services.h

    r103939e r0a8f070  
    4343typedef enum {
    4444        SERVICE_NONE       = 0,
    45         SERVICE_LOADER     = FOURCC('l', 'o', 'a', 'd'),
    4645        SERVICE_VFS        = FOURCC('v', 'f', 's', ' '),
    4746        SERVICE_LOC        = FOURCC('l', 'o', 'c', ' '),
    4847        SERVICE_SYSMAN     = FOURCC('s', 'y', 's', 'm'),
     48        SERVICE_TASKMAN    = FOURCC('t', 's', 'k', 'm'),
    4949        SERVICE_LOGGER     = FOURCC('l', 'o', 'g', 'g'),
    5050        SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
  • uspace/lib/c/include/ipc/taskman.h

    r103939e r0a8f070  
    11/*
    2  * Copyright (c) 2009 Martin Decky
     2 * Copyright (c) 2015 Michal Koutny
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup ns
     29/** @addtogroup libcipc
    3030 * @{
    3131 */
     32/** @file
     33 */
    3234
    33 #ifndef NS_CLONABLE_H__
    34 #define NS_CLONABLE_H__
     35#ifndef LIBC_IPC_TASKMAN_H_
     36#define LIBC_IPC_TASKMAN_H_
    3537
    3638#include <ipc/common.h>
    37 #include <ipc/services.h>
    38 #include <abi/ipc/interfaces.h>
    39 #include <stdbool.h>
    4039
    41 extern errno_t ns_clonable_init(void);
    4240
    43 extern bool ns_service_is_clonable(service_t, iface_t);
    44 extern void ns_clonable_register(ipc_call_t *);
    45 extern void ns_clonable_forward(service_t, iface_t, ipc_call_t *);
     41typedef enum {
     42        TASKMAN_HELLO = IPC_FIRST_USER_METHOD,
     43} taskman_request_t;
     44
     45typedef enum {
     46        TASKMAN_CONNECT_TO_LOADER = 0,
     47        TASKMAN_LOADER_TO_NS,
     48        TASKMAN_LOADER_CALLBACK,
     49        TASKMAN_CONTROL
     50} taskman_interface_t;
    4651
    4752#endif
    4853
    49 /**
    50  * @}
     54/** @}
    5155 */
  • uspace/lib/c/include/loader/pcb.h

    r103939e r0a8f070  
    4646};
    4747
     48/* Forward declaration */
     49struct async_sess;
     50typedef struct async_sess async_sess_t;
     51
    4852/** Program Control Block.
    4953 *
     
    5761        entry_point_t entry;
    5862
     63        /** Primary session to broker. */
     64        async_sess_t *session_primary;
     65       
    5966        /** Current working directory. */
    6067        char *cwd;
  • uspace/lib/c/include/ns.h

    r103939e r0a8f070  
    4747
    4848extern errno_t ns_ping(void);
    49 extern errno_t ns_intro(task_id_t);
    5049extern async_sess_t *ns_session_get(void);
    5150
  • uspace/srv/loader/main.c

    r103939e r0a8f070  
    3434 *
    3535 * The program loader is a special init binary. Its image is used
    36  * to create a new task upon a @c task_spawn syscall. The syscall
    37  * returns the id of a phone connected to the newly created task.
    38  *
    39  * The caller uses this phone to send the pathname and various other
     36 * to create a new task upon a @c task_spawn syscall. It has a phone connected
     37 * to the caller of te syscall. The formal caller (taskman) performs a
     38 * handshake with loader so that apparent caller can communicate with the
     39 * loader.
     40 *
     41 * The apparent caller uses his phone to send the pathname and various other
    4042 * information to the loader. This is normally done by the C library
    4143 * and completely hidden from applications.
    4244 */
     45
    4346
    4447#include <stdio.h>
     
    4750#include <stddef.h>
    4851#include <ipc/services.h>
    49 #include <ipc/loader.h>
    50 #include <ns.h>
    51 #include <loader/pcb.h>
     52#include <as.h>
     53#include <async.h>
     54#include <elf/elf.h>
     55#include <elf/elf_load.h>
    5256#include <entry_point.h>
    5357#include <errno.h>
    54 #include <async.h>
     58#include <fcntl.h>
     59#include <fibril_synch.h>
     60#include <ipc/loader.h>
     61#include <loader/pcb.h>
    5562#include <str.h>
    56 #include <as.h>
    57 #include <elf/elf.h>
    58 #include <elf/elf_load.h>
     63#include <sys/types.h>
     64#include <taskman.h>
     65#include <unistd.h>
    5966#include <vfs/vfs.h>
    6067#include <vfs/inbox.h>
     
    7380/** The Program control block */
    7481static pcb_t pcb;
     82
     83/** Primary IPC session */
     84static async_sess_t *session_primary = NULL;
    7585
    7686/** Current working directory */
     
    92102/** Used to limit number of connections to one. */
    93103static bool connected = false;
     104
     105/** Ensure synchronization of handshake and connection fibrils. */
     106static bool handshake_complete = false;
     107FIBRIL_MUTEX_INITIALIZE(handshake_mtx);
     108FIBRIL_CONDVAR_INITIALIZE(handshake_cv);
    94109
    95110static void ldr_get_taskid(ipc_call_t *req)
     
    319334        DPRINTF("PCB set.\n");
    320335
     336        pcb.session_primary = session_primary;
     337
    321338        pcb.cwd = cwd;
    322339
     
    373390static void ldr_connection(ipc_call_t *icall, void *arg)
    374391{
     392        /* Wait for handshake */
     393        fibril_mutex_lock(&handshake_mtx);
     394        while (!handshake_complete) {
     395                fibril_condvar_wait(&handshake_cv, &handshake_mtx);
     396        }
     397        fibril_mutex_unlock(&handshake_mtx);
     398
    375399        /* Already have a connection? */
    376400        if (connected) {
     
    428452}
    429453
     454static errno_t ldr_taskman_handshake(void)
     455{
     456        errno_t retval = EOK;
     457
     458        fibril_mutex_lock(&handshake_mtx);
     459        session_primary = taskman_handshake();
     460        if (session_primary == NULL) {
     461                retval = errno;
     462                goto finish;
     463        }
     464
     465        async_sess_t *session_tm = async_session_primary_swap(session_primary);
     466        (void)async_hangup(session_tm);
     467
     468        handshake_complete = true;
     469
     470finish:
     471        fibril_condvar_signal(&handshake_cv);
     472        fibril_mutex_unlock(&handshake_mtx);
     473
     474        return retval;
     475}
     476
    430477/** Program loader main function.
    431478 */
    432479int main(int argc, char *argv[])
    433480{
    434         /* Introduce this task to the NS (give it our task ID). */
    435         task_id_t id = task_get_id();
    436         errno_t rc = ns_intro(id);
    437         if (rc != EOK)
     481        /* Set a handler of incomming connections. */
     482        async_set_fallback_port_handler(ldr_connection, NULL);
     483       
     484        /* Handshake with taskman */
     485        int rc = ldr_taskman_handshake();
     486        if (rc != EOK) {
     487                DPRINTF("Failed taskman handshake (%i).\n", errno);
    438488                return rc;
    439 
    440         /* Register at naming service. */
    441         rc = service_register(SERVICE_LOADER, INTERFACE_LOADER,
    442             ldr_connection, NULL);
    443         if (rc != EOK)
    444                 return rc;
    445 
     489        }
     490
     491        /* Handle client connections */
    446492        async_manager();
    447 
     493        //TODO retval?
     494       
    448495        /* Never reached */
    449496        return 0;
  • uspace/srv/ns/Makefile

    r103939e r0a8f070  
    3535        ns.c \
    3636        service.c \
    37         clonable.c \
    3837        task.c
    3938
  • uspace/srv/ns/ns.c

    r103939e r0a8f070  
    4646#include "ns.h"
    4747#include "service.h"
    48 #include "clonable.h"
    4948#include "task.h"
    5049
     
    6160                 * Client requests to be connected to a service.
    6261                 */
    63                 if (ns_service_is_clonable(service, iface)) {
    64                         ns_clonable_forward(service, iface, icall);
    65                 } else {
    66                         ns_service_forward(service, iface, icall);
    67                 }
    68 
     62                ns_service_forward(service, iface, icall);
    6963                return;
    7064        }
     
    9286                         * Server requests service registration.
    9387                         */
    94                         if (ns_service_is_clonable(service, iface)) {
    95                                 ns_clonable_register(&call);
    96                                 continue;
    97                         } else {
    98                                 retval = ns_service_register(service, iface);
    99                         }
     88                        retval = ns_service_register(service, iface);
    10089
    10190                        break;
     
    116105                        break;
    117106                case NS_RETVAL:
    118                         retval = ns_task_retval(&call);
     107                        // TODO move to taskman
     108                        retval = EOK;
     109                        //retval = ns_task_retval(&call);
    119110                        break;
    120111                default:
     
    140131                return rc;
    141132
    142         rc = ns_clonable_init();
    143         if (rc != EOK)
    144                 return rc;
    145 
    146133        rc = task_init();
    147134        if (rc != EOK)
Note: See TracChangeset for help on using the changeset viewer.