Changeset 1be7bee in mainline


Ignore:
Timestamp:
2019-08-07T04:20:30Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
70d28e8
Parents:
fe86d9d
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-10-05 21:17:40)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 04:20:30)
Message:

sysman: Move task retval and waiting logic to taskman (partially)

  • two important sessions: NS and taskman
  • depending on boot task vs spawned task those sessions are initiated differently

Conflicts:

uspace/lib/c/generic/async.c
uspace/lib/c/generic/libc.c
uspace/lib/c/generic/task.c
uspace/lib/c/include/ipc/ns.h
uspace/lib/c/include/task.h
uspace/lib/posix/source/sys/wait.c
uspace/srv/loader/main.c
uspace/srv/ns/ns.c

Location:
uspace
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/trace/trace.c

    rfe86d9d r1be7bee  
    887887                printf("Waiting for task to exit.\n");
    888888
    889                 rc = task_wait_task_id(task_id, &texit, &retval);
     889                rc = task_wait_task_id(task_id, TASK_WAIT_EXIT, &texit, &retval);
    890890                if (rc != EOK) {
    891891                        printf("Failed waiting for task.\n");
  • uspace/lib/c/generic/async/client.c

    rfe86d9d r1be7bee  
    174174
    175175        if (session != NULL) {
     176                // TODO extract common part with async_connect_me_to
    176177                session_ns->iface = 0;
    177178                session->mgmt = EXCHANGE_ATOMIC;
     
    195196
    196197/** Initialize the async framework.
    197  *
    198  */
    199 void __async_client_init(async_sess_t *session)
     198 * @param arg_session_primary Primary session (to naming service).
     199 *
     200 */
     201void __async_client_init(async_sess_t *arg_session_primary)
    200202{
    201203        if (fibril_rmutex_initialize(&message_mutex) != EOK)
    202204                abort();
    203205
    204         if (session == NULL) {
     206        if (arg_session_primary == NULL) {
    205207                session_primary = create_session_primary();
    206208        } else {
    207                 session_primary = session;
     209                session_primary = arg_session_primary;
    208210        }
    209211
  • uspace/lib/c/generic/libc.c

    rfe86d9d r1be7bee  
    4848#include "private/libc.h"
    4949#include "private/async.h"
    50 #include "private/malloc.h"
    5150#include "private/io.h"
    5251#include "private/fibril.h"
     52#include "private/malloc.h"
     53#include "private/ns.h" // TODO maybe better filename for session_primary
     54#include "private/task.h"
     55
    5356
    5457#ifdef CONFIG_RTLD
     
    108111        if (__pcb == NULL) {
    109112                __async_client_init(NULL);
     113                __task_init(NULL);
    110114        } else {
    111115                __async_client_init(__pcb->session_primary);
     116                __task_init(__pcb->session_taskman);
    112117        }
    113118        __async_ports_init();
  • uspace/lib/c/generic/task.c

    rfe86d9d r1be7bee  
    3535 */
    3636
    37 #include <task.h>
    38 #include <loader/loader.h>
    39 #include <stdarg.h>
    40 #include <str.h>
    41 #include <ipc/ns.h>
    42 #include <macros.h>
    4337#include <assert.h>
    4438#include <async.h>
     
    4640#include <ns.h>
    4741#include <stdlib.h>
     42#include <ipc/taskman.h>
    4843#include <libc.h>
     44#include <loader/loader.h>
     45#include <macros.h>
     46#include <malloc.h>
     47#include <stdarg.h>
     48#include <str.h>
     49#include <task.h>
     50#include <vfs/vfs.h>
    4951#include "private/ns.h"
    50 #include <vfs/vfs.h>
     52#include "private/task.h"
     53
     54static async_sess_t *session_taskman = NULL;
    5155
    5256task_id_t task_get_id(void)
     
    6468}
    6569
     70static async_exch_t *taskman_exchange_begin(void)
     71{
     72        /* Lazy connection */
     73        if (session_taskman == NULL) {
     74                // TODO unify exchange mgmt with taskman_handshake/__init
     75                session_taskman = service_connect_blocking(EXCHANGE_SERIALIZE,
     76                    SERVICE_TASKMAN,
     77                    TASKMAN_CONTROL,
     78                    0);
     79        }
     80
     81        if (session_taskman == NULL) {
     82                return NULL;
     83        }
     84
     85        async_exch_t *exch = async_exchange_begin(session_taskman);
     86        return exch;
     87}
     88
     89static void taskman_exchange_end(async_exch_t *exch)
     90{
     91        async_exchange_end(exch);
     92}
     93
    6694/** Set the task name.
    6795 *
     
    88116{
    89117        return (errno_t) __SYSCALL1(SYS_TASK_KILL, (sysarg_t) &task_id);
     118}
     119
     120/** Setup waiting for a task.
     121 *
     122 * If the task finishes after this call succeeds, it is guaranteed that
     123 * task_wait(wait, &texit, &retval) will return correct return value for
     124 * the task.
     125 *
     126 * @param id   ID of the task to setup waiting for.
     127 * @param wait Information necessary for the later task_wait call is stored here.
     128 *
     129 * @return EOK on success, else error code.
     130 */
     131static errno_t task_setup_wait(task_id_t id, task_wait_t *wait)
     132{
     133        async_exch_t *exch = taskman_exchange_begin();
     134        if (exch == NULL)
     135                        return EIO;
     136
     137        wait->aid = async_send_3(exch, TASKMAN_WAIT, LOWER32(id), UPPER32(id),
     138            wait->flags, &wait->result);
     139        taskman_exchange_end(exch);
     140
     141        return EOK;
    90142}
    91143
     
    312364}
    313365
    314 /** Setup waiting for a task.
    315  *
    316  * If the task finishes after this call succeeds, it is guaranteed that
    317  * task_wait(wait, &texit, &retval) will return correct return value for
    318  * the task.
    319  *
    320  * @param id   ID of the task to setup waiting for.
    321  * @param wait Information necessary for the later task_wait call is stored here.
    322  *
    323  * @return EOK on success, else error code.
    324  */
    325 errno_t task_setup_wait(task_id_t id, task_wait_t *wait)
    326 {
    327         async_sess_t *sess_ns = get_session_primary();
    328         if (sess_ns == NULL)
    329                 return EIO;
    330 
    331         async_exch_t *exch = async_exchange_begin(sess_ns);
    332 
    333         wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id),
    334             &wait->result);
    335         async_exchange_end(exch);
    336 
    337         return EOK;
    338 }
    339 
    340366/** Cancel waiting for a task.
    341367 *
     
    391417 *
    392418 * @param id ID of the task to wait for.
     419 * @param flags  Specify for which task output we wait
    393420 * @param texit  Store type of task exit here.
    394421 * @param retval Store return value of the task here.
     
    396423 * @return EOK on success, else error code.
    397424 */
    398 errno_t task_wait_task_id(task_id_t id, task_exit_t *texit, int *retval)
     425errno_t task_wait_task_id(task_id_t id, int flags, task_exit_t *texit, int *retval)
    399426{
    400427        task_wait_t wait;
     428        wait.flags = flags;
    401429        errno_t rc = task_setup_wait(id, &wait);
     430
    402431        if (rc != EOK)
    403432                return rc;
     
    408437errno_t task_retval(int val)
    409438{
    410         async_sess_t *sess_ns = get_session_primary();
    411         if (sess_ns == NULL)
     439        async_exch_t *exch = taskman_exchange_begin();
     440        if (exch == NULL)
    412441                return EIO;
    413442
    414         async_exch_t *exch = async_exchange_begin(sess_ns);
    415         errno_t rc = (errno_t) async_req_1_0(exch, NS_RETVAL, val);
    416         async_exchange_end(exch);
    417 
     443        int rc = (int) async_req_1_0(exch, TASKMAN_RETVAL, val);
     444        taskman_exchange_end(exch);
     445       
    418446        return rc;
    419447}
    420448
     449
     450void __task_init(async_sess_t *sess)
     451{
     452        assert(session_taskman == NULL);
     453        session_taskman = sess;
     454}
     455
    421456/** @}
    422457 */
  • uspace/lib/c/include/ipc/ns.h

    rfe86d9d r1be7bee  
    4242        NS_REGISTER,
    4343        NS_REGISTER_BROKER,
    44         NS_TASK_WAIT,
    45         NS_ID_INTRO,
    46         NS_RETVAL
     44        NS_ID_INTRO
    4745} ns_request_t;
    4846
  • uspace/lib/c/include/ipc/taskman.h

    rfe86d9d r1be7bee  
    4040
    4141typedef enum {
    42         TASKMAN_HELLO = IPC_FIRST_USER_METHOD,
     42        TASKMAN_WAIT = IPC_FIRST_USER_METHOD,
     43        TASKMAN_RETVAL
    4344} taskman_request_t;
    4445
  • uspace/lib/c/include/loader/pcb.h

    rfe86d9d r1be7bee  
    6464        async_sess_t *session_primary;
    6565       
     66        /** Session to taskman (typically spawn parent) */
     67        async_sess_t *session_taskman;
     68       
    6669        /** Current working directory. */
    6770        char *cwd;
  • uspace/lib/c/include/task.h

    rfe86d9d r1be7bee  
    4242#include <types/task.h>
    4343
     44#define TASK_WAIT_EXIT   0x1
     45#define TASK_WAIT_RETVAL 0x2
     46
    4447typedef struct {
     48        int flags;
    4549        ipc_call_t result;
    4650        aid_t aid;
    4751} task_wait_t;
    4852
    49 struct _TASK;
    50 typedef struct _TASK task_t;
    5153
    5254extern task_id_t task_get_id(void);
     
    6365    __attribute__((sentinel));
    6466
    65 extern errno_t task_setup_wait(task_id_t, task_wait_t *);
     67// if there is possibility for further wait, modify task_wait
     68extern errno_t task_wait(task_wait_t *, task_exit_t *, int *);
     69extern errno_t task_wait_task_id(task_id_t, int, task_exit_t *, int *);
     70// similar to listen and socket duplication
     71extern errno_t task_wait_any(task_wait_t *, task_id_t *, task_exit_t *, int *,
     72    task_wait_t *);
     73
     74//extern int task_wait_any(int, task_exit_t *, int *);
     75// alternative
     76// task_wait_t is output param, actual result is obtained via task_wait call
     77//extern int task_wait_any(task_wait_t *, int);
     78
    6679extern void task_cancel_wait(task_wait_t *);
    67 extern errno_t task_wait(task_wait_t *, task_exit_t *, int *);
    68 extern errno_t task_wait_task_id(task_id_t, task_exit_t *, int *);
     80
    6981extern errno_t task_retval(int);
     82//TODO
     83//extern int task_exit(int);
    7084
    7185#endif
  • uspace/lib/posix/src/sys/wait.c

    rfe86d9d r1be7bee  
    101101        assert(options == 0 /* None of the options are supported. */);
    102102
     103        int flags = TASK_WAIT_RETVAL | TASK_WAIT_EXIT;
    103104        task_exit_t texit;
    104105        int retval;
    105106
    106         if (failed(task_wait_task_id((task_id_t) pid, &texit, &retval))) {
     107        // TODO repeat wait for both retval and exit
     108        if (failed(task_wait_task_id((task_id_t) pid, flags, &texit, &retval))) {
    107109                /* Unable to retrieve status. */
    108110                return (pid_t) -1;
  • uspace/srv/loader/main.c

    rfe86d9d r1be7bee  
    8484static async_sess_t *session_primary = NULL;
    8585
     86/** Session to taskman (typically our spawner) */
     87static async_sess_t *session_taskman = NULL;
     88
    8689/** Current working directory */
    8790static char *cwd = NULL;
     
    335338
    336339        pcb.session_primary = session_primary;
     340        pcb.session_taskman = session_taskman;
    337341
    338342        pcb.cwd = cwd;
     
    452456}
    453457
     458/** Handshake with taskman
     459 *
     460 * Taskman is our spawn parent, i.e. PHONE_INITIAL is connected to it.
     461 * Goal of the handshake is to obtain phone to naming service and also keep the
     462 * session to taskman.
     463 *
     464 * @return EOK on success, for errors see taskman_handshake()
     465 */
    454466static errno_t ldr_taskman_handshake(void)
    455467{
     468        assert(session_primary == NULL);
     469        assert(session_taskman == NULL);
     470
    456471        errno_t retval = EOK;
    457472
     
    463478        }
    464479
    465         async_sess_t *session_tm = async_session_primary_swap(session_primary);
    466         (void)async_hangup(session_tm);
     480        session_taskman = async_session_primary_swap(session_primary);
    467481
    468482        handshake_complete = true;
  • uspace/srv/ns/ns.c

    rfe86d9d r1be7bee  
    4343#include <stdio.h>
    4444#include <errno.h>
    45 #include <macros.h>
    4645#include "ns.h"
    4746#include "service.h"
     
    9695                        retval = EOK;
    9796                        break;
    98                 case NS_TASK_WAIT:
    99                         id = (task_id_t)
    100                             MERGE_LOUP32(ipc_get_arg1(&call), ipc_get_arg2(&call));
    101                         wait_for_task(id, &call);
    102                         continue;
    10397                case NS_ID_INTRO:
    10498                        retval = ns_task_id_intro(&call);
    105                         break;
    106                 case NS_RETVAL:
    107                         // TODO move to taskman
    108                         retval = EOK;
    109                         //retval = ns_task_retval(&call);
    11099                        break;
    111100                default:
  • uspace/srv/taskman/Makefile

    rfe86d9d r1be7bee  
    3232
    3333SOURCES = \
    34         main.c
     34        main.c \
     35        task.c
    3536
    3637include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/taskman/main.c

    rfe86d9d r1be7bee  
    3434#include <ipc/taskman.h>
    3535#include <loader/loader.h>
     36#include <macros.h>
    3637#include <ns.h>
    3738#include <stdio.h>
    3839#include <stdlib.h>
    3940
    40 #define NAME "taskman"
     41#include "task.h"
     42#include "taskman.h"
    4143
    4244//TODO move to appropriate header file
     
    5658static void connect_to_loader(ipc_callid_t iid, ipc_call_t *icall)
    5759{
     60        //TODO explain why we don't explicitly accept connection request
    5861        /* Spawn a loader. */
    5962        int rc = loader_spawn("loader");
     
    99102}
    100103
     104static void taskman_ctl_wait(ipc_callid_t iid, ipc_call_t *icall)
     105{
     106        task_id_t id = (task_id_t)
     107            MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall));
     108        int flags = IPC_GET_ARG3(*icall);
     109
     110        wait_for_task(id, flags, iid, icall);
     111}
     112
     113static void taskman_ctl_retval(ipc_callid_t iid, ipc_call_t *icall)
     114{
     115        printf("%s:%i\n", __func__, __LINE__);
     116        int rc = task_set_retval(icall);
     117        async_answer_0(iid, rc);
     118}
     119
     120static void control_connection_loop(void)
     121{
     122        while (true) {
     123                ipc_call_t call;
     124                ipc_callid_t callid = async_get_call(&call);
     125
     126                if (!IPC_GET_IMETHOD(call)) {
     127                        /* Client disconnected */
     128                        break;
     129                }
     130
     131                switch (IPC_GET_IMETHOD(call)) {
     132                case TASKMAN_WAIT:
     133                        taskman_ctl_wait(callid, &call);
     134                        break;
     135                case TASKMAN_RETVAL:
     136                        taskman_ctl_retval(callid, &call);
     137                        break;
     138                default:
     139                        async_answer_0(callid, ENOENT);
     140                }
     141        }
     142}
     143
     144static void control_connection(ipc_callid_t iid, ipc_call_t *icall)
     145{
     146        /* First, accept connection */
     147        async_answer_0(iid, EOK);
     148
     149        // TODO register task to hash table
     150        control_connection_loop();
     151}
     152
    101153static void loader_callback(ipc_callid_t iid, ipc_call_t *icall)
    102154{
     
    134186                loader_to_ns(iid, icall);
    135187                break;
     188        case TASKMAN_CONTROL:
     189                control_connection(iid, icall);
     190                // ---- interrupt here ----
     191                //   implement control connection body (setup wait)
     192                // ------------------------
     193                break;
    136194        default:
    137195                /* Unknown interface */
     
    146204        case TASKMAN_LOADER_CALLBACK:
    147205                loader_callback(iid, icall);
     206                // TODO register task to hashtable
     207                control_connection_loop();
    148208                break;
    149209        default:
     
    161221
    162222        prodcons_initialize(&sess_queue);
     223        int rc = task_init();
     224        if (rc != EOK) {
     225                return rc;
     226        }
    163227
    164228        /* We're service too */
    165         int rc = service_register(SERVICE_TASKMAN);
     229        rc = service_register(SERVICE_TASKMAN);
    166230        if (rc != EOK) {
    167231                printf("Cannot register at naming service (%i).", rc);
Note: See TracChangeset for help on using the changeset viewer.