Changeset 62273d1 in mainline


Ignore:
Timestamp:
2019-08-07T04:27:24Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
2f44fafd
Parents:
70d28e8
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-10-08 21:46:22)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 04:27:24)
Message:

taskman: Implement simple task exit monitoring

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/tester/proc/dummy_task.c

    r70d28e8 r62273d1  
    4848static void dummy_fail(void)
    4949{
     50        task_id_t id = task_get_id();
     51        printf("Gonna shoot myself (%" PRIu64 ").\n", id);
    5052        behavior_func_t func = NULL;
    5153        func();
  • uspace/app/tester/proc/task_wait.c

    r70d28e8 r62273d1  
    6767        task_exit_t texit;
    6868
    69         TPRINTF("11 match");
     69        TPRINTF("11 match\n");
    7070
    7171        task_wait_set(&wait, TASK_WAIT_EXIT);
     
    7373        TASSERT(rc == EOK);
    7474
    75         rc = task_wait(&wait, &texit, &retval);
     75        TPRINTF("waiting...");
     76        rc = task_wait(&wait, &texit, &retval);
     77        TPRINTF("done.\n");
    7678        TASSERT(rc == EOK);
    7779        TASSERT(texit == TASK_EXIT_UNEXPECTED);
    78         TPRINTF("OK");
     80        TPRINTF("OK\n");
    7981        /* ---- */
    8082       
    81         TPRINTF("12 lost wait");
     83        TPRINTF("12 lost wait\n");
    8284
    8385        task_wait_set(&wait, TASK_WAIT_RETVAL);
     
    8587        TASSERT(rc == EOK);
    8688
    87         rc = task_wait(&wait, &texit, &retval);
     89        TPRINTF("waiting...");
     90        rc = task_wait(&wait, &texit, &retval);
     91        TPRINTF("done.\n");
    8892        TASSERT(rc == EINVAL);
    89         TPRINTF("OK");
    90         /* ---- */
    91 
    92         TPRINTF("13 partial match");
     93        TPRINTF("OK\n");
     94        /* ---- */
     95
     96        TPRINTF("13 partial match\n");
    9397
    9498        task_wait_set(&wait, TASK_WAIT_RETVAL | TASK_WAIT_EXIT);
     
    96100        TASSERT(rc == EOK);
    97101
    98         rc = task_wait(&wait, &texit, &retval);
     102        TPRINTF("waiting...");
     103        rc = task_wait(&wait, &texit, &retval);
     104        TPRINTF("done.\n");
    99105        TASSERT(rc == EOK);
    100106        TASSERT(texit == TASK_EXIT_UNEXPECTED);
    101107        /* retval is undefined */
    102         TPRINTF("OK");
    103         /* ---- */
    104 
    105         TPRINTF("21 ignore retval");
     108        TPRINTF("OK\n");
     109        /* ---- */
     110
     111        TPRINTF("21 ignore retval\n");
    106112
    107113        task_wait_set(&wait, TASK_WAIT_EXIT);
     
    109115        TASSERT(rc == EOK);
    110116
    111         rc = task_wait(&wait, &texit, &retval);
     117        TPRINTF("waiting...");
     118        rc = task_wait(&wait, &texit, &retval);
     119        TPRINTF("done.\n");
    112120        TASSERT(rc == EOK);
    113121        TASSERT(texit == TASK_EXIT_NORMAL);
    114122        /* retval is unknown */
    115         TPRINTF("OK");
    116         /* ---- */
    117 
    118         TPRINTF("22 good match");
     123        TPRINTF("OK\n");
     124        /* ---- */
     125
     126        TPRINTF("22 good match\n");
    119127
    120128        task_wait_set(&wait, TASK_WAIT_RETVAL);
     
    122130        TASSERT(rc == EOK);
    123131
    124         rc = task_wait(&wait, &texit, &retval);
     132        TPRINTF("waiting...");
     133        rc = task_wait(&wait, &texit, &retval);
     134        TPRINTF("done.\n");
    125135        TASSERT(rc == EOK);
    126136        /* exit is not expected */
    127137        TASSERT(retval == EOK);
    128138        task_kill(tid); /* Terminate daemon */
    129         TPRINTF("OK");
    130         /* ---- */
    131 
    132         TPRINTF("23 partial match (non-exited task)");
     139        TPRINTF("OK\n");
     140        /* ---- */
     141
     142        TPRINTF("23 partial match (non-exited task)\n");
    133143
    134144        // TODO should update wait for synchronized exit waiting
     
    137147        TASSERT(rc == EOK);
    138148
    139         rc = task_wait(&wait, &texit, &retval);
     149        TPRINTF("waiting...");
     150        rc = task_wait(&wait, &texit, &retval);
     151        TPRINTF("done.\n");
    140152        TASSERT(rc == EOK);
    141153        /* exit is not expected */
    142154        TASSERT(retval == EOK);
    143155        task_kill(tid); /* Terminate daemon */
    144         TPRINTF("OK");
    145         /* ---- */
    146 
    147         TPRINTF("31 on exit return");
     156        TPRINTF("OK\n");
     157        /* ---- */
     158
     159        TPRINTF("31 on exit return\n");
    148160
    149161        task_wait_set(&wait, TASK_WAIT_EXIT);
     
    151163        TASSERT(rc == EOK);
    152164
    153         rc = task_wait(&wait, &texit, &retval);
     165        TPRINTF("waiting...");
     166        rc = task_wait(&wait, &texit, &retval);
     167        TPRINTF("done.\n");
    154168        TASSERT(rc == EOK);
    155169        TASSERT(texit == TASK_EXIT_NORMAL);
    156170        /* retval is unknown */
    157         TPRINTF("OK");
    158         /* ---- */
    159 
    160 
    161         TPRINTF("32 keep retval until exit");
     171        TPRINTF("OK\n");
     172        /* ---- */
     173
     174
     175        TPRINTF("32 keep retval until exit\n");
    162176
    163177        task_wait_set(&wait, TASK_WAIT_RETVAL);
     
    165179        TASSERT(rc == EOK);
    166180
    167         rc = task_wait(&wait, &texit, &retval);
     181        TPRINTF("waiting...");
     182        rc = task_wait(&wait, &texit, &retval);
     183        TPRINTF("done.\n");
    168184        TASSERT(rc == EOK);
    169185        /* exit is unknown */
     
    172188        rc = task_kill(tid);
    173189        TASSERT(rc == ENOENT);
    174         TPRINTF("OK");
    175         /* ---- */
    176 
    177         TPRINTF("33 double good match");
     190        TPRINTF("OK\n");
     191        /* ---- */
     192
     193        TPRINTF("33 double good match\n");
    178194
    179195        task_wait_set(&wait, TASK_WAIT_RETVAL | TASK_WAIT_EXIT);
     
    181197        TASSERT(rc == EOK);
    182198
    183         rc = task_wait(&wait, &texit, &retval);
     199        TPRINTF("waiting...");
     200        rc = task_wait(&wait, &texit, &retval);
     201        TPRINTF("done.\n");
    184202        TASSERT(rc == EOK);
    185203        TASSERT(texit == TASK_EXIT_NORMAL);
    186204        TASSERT(retval == EOK);
    187         TPRINTF("OK");
     205        TPRINTF("OK\n");
    188206        /* ---- */
    189207
  • uspace/lib/c/include/types/task.h

    r70d28e8 r62273d1  
    3737
    3838typedef enum {
     39        TASK_EXIT_RUNNING,   /**< Internal taskman value. */
    3940        TASK_EXIT_NORMAL,
    4041        TASK_EXIT_UNEXPECTED
  • uspace/srv/taskman/main.c

    r70d28e8 r62273d1  
    7979        async_exchange_end(exch);
    8080
     81        // TODO leak? what happens with referenced sessions
    8182        free(sess_ref);
    8283
     
    116117        int rc = task_set_retval(icall);
    117118        async_answer_0(iid, rc);
     119}
     120
     121static void task_exit_event(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     122{
     123        printf("%s:%i\n", __func__, __LINE__);
     124        // TODO design substitution for taskmon (monitoring)
     125        task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall));
     126        task_terminated(id, (task_exit_t)arg);
    118127}
    119128
     
    161170                async_answer_0(iid, ENOMEM);
    162171        }
    163        
    164172
    165173        /* Create callback connection */
     
    170178                return;
    171179        }
     180
     181        /* Remember task_id */
     182        int rc = task_id_intro(icall);
     183
     184        if (rc != EOK) {
     185                async_answer_0(iid, rc);
     186                free(sess_ref);
     187                return;
     188        }
    172189        async_answer_0(iid, EOK);
    173190
     191        /* Notify spawners */
    174192        link_initialize(&sess_ref->link);
    175193        prodcons_produce(&sess_queue, &sess_ref->link);
     
    220238        printf(NAME ": HelenOS task manager\n");
    221239
     240        /* Initialization */
    222241        prodcons_initialize(&sess_queue);
    223242        int rc = task_init();
     
    226245        }
    227246
     247        rc = async_event_subscribe(EVENT_EXIT, task_exit_event, (void *)EVENT_EXIT);
     248        if (rc != EOK) {
     249                printf("Cannot register for exit events (%i).\n", rc);
     250                return rc;
     251        }
     252
     253        rc = async_event_subscribe(EVENT_FAULT, task_exit_event, (void *)EVENT_FAULT);
     254        if (rc != EOK) {
     255                printf("Cannot register for fault events (%i).\n", rc);
     256                return rc;
     257        }
     258
    228259        /* We're service too */
    229260        rc = service_register(SERVICE_TASKMAN);
    230261        if (rc != EOK) {
    231                 printf("Cannot register at naming service (%i).", rc);
     262                printf("Cannot register at naming service (%i).\n", rc);
    232263                return rc;
    233264        }
  • uspace/srv/taskman/task.c

    r70d28e8 r62273d1  
    5252       
    5353        task_id_t id;    /**< Task ID. */
    54         bool finished;   /**< Task is done. */
     54        task_exit_t exit;/**< Task is done. */
    5555        bool have_rval;  /**< Task returned a value. */
    5656        int retval;      /**< The return value. */
     
    185185               
    186186                hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
    187                 if (!ht->finished)
     187                if (ht->exit == TASK_EXIT_RUNNING)
    188188                        continue;
    189189               
    190190                if (!(pr->callid & IPC_CALLID_NOTIFICATION)) {
    191                         texit = ht->have_rval ? TASK_EXIT_NORMAL :
    192                             TASK_EXIT_UNEXPECTED;
     191                        texit = ht->exit;
    193192                        async_answer_2(pr->callid, EOK, texit,
    194193                            ht->retval);
     
    216215        }
    217216       
    218         if (ht->finished) {
    219                 task_exit_t texit = ht->have_rval ? TASK_EXIT_NORMAL :
    220                     TASK_EXIT_UNEXPECTED;
     217        if (ht->exit != TASK_EXIT_RUNNING) {
     218                task_exit_t texit = ht->exit;
    221219                async_answer_2(callid, EOK, texit, ht->retval);
    222220                return;
     
    242240}
    243241
    244 int ns_task_id_intro(ipc_call_t *call)
    245 {
    246        
    247         task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
    248 
    249         ht_link_t *link = hash_table_find(&phone_to_id, &call->in_phone_hash);
     242int task_id_intro(ipc_call_t *call)
     243{
     244        // TODO think about task_id reuse and this
     245        // R lock
     246        ht_link_t *link = hash_table_find(&task_hash_table, &call->in_task_id);
     247        // R unlock
    250248        if (link != NULL)
    251249                return EEXISTS;
    252        
    253         p2i_entry_t *entry = (p2i_entry_t *) malloc(sizeof(p2i_entry_t));
    254         if (entry == NULL)
    255                 return ENOMEM;
    256250       
    257251        hashed_task_t *ht = (hashed_task_t *) malloc(sizeof(hashed_task_t));
    258252        if (ht == NULL)
    259253                return ENOMEM;
    260        
    261         /*
    262          * Insert into the phone-to-id map.
    263          */
    264        
    265         entry->in_phone_hash = call->in_phone_hash;
    266         entry->id = id;
    267         hash_table_insert(&phone_to_id, &entry->link);
    268        
     254
    269255        /*
    270256         * Insert into the main table.
    271257         */
    272        
    273         ht->id = id;
    274         ht->finished = false;
     258        ht->id = call->in_task_id;
     259        ht->exit = TASK_EXIT_RUNNING;
    275260        ht->have_rval = false;
    276261        ht->retval = -1;
     262        // W lock
    277263        hash_table_insert(&task_hash_table, &ht->link);
    278        
    279         return EOK;
    280 }
    281 
    282 static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id)
    283 {
    284         ht_link_t *link = hash_table_find(&phone_to_id, &phone_hash);
    285         if (link == NULL)
    286                 return ENOENT;
    287        
    288         p2i_entry_t *entry = hash_table_get_inst(link, p2i_entry_t, link);
    289         *id = entry->id;
     264        // W unlock
    290265       
    291266        return EOK;
     
    302277            hash_table_get_inst(link, hashed_task_t, link) : NULL;
    303278       
    304         if ((ht == NULL) || (ht->finished))
    305                 return EOK; // TODO EINVAL when registration works;
    306        
    307         ht->finished = true;
     279        if ((ht == NULL) || (ht->exit != TASK_EXIT_RUNNING))
     280                return EINVAL;
     281       
     282        // TODO process additional flag to retval
    308283        ht->have_rval = true;
    309284        ht->retval = IPC_GET_ARG1(*call);
     
    314289}
    315290
    316 int ns_task_disconnect(ipc_call_t *call)
    317 {
    318         task_id_t id;
    319         int rc = get_id_by_phone(call->in_phone_hash, &id);
    320         if (rc != EOK)
    321                 return rc;
    322        
    323         /* Delete from phone-to-id map. */
    324         hash_table_remove(&phone_to_id, &call->in_phone_hash);
    325        
     291void task_terminated(task_id_t id, task_exit_t texit)
     292{
    326293        /* Mark task as finished. */
     294        // R lock
    327295        ht_link_t *link = hash_table_find(&task_hash_table, &id);
     296        // R unlock
    328297        if (link == NULL)
    329                 return EOK;
     298                return;
    330299
    331300        hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link);
    332301       
    333         ht->finished = true;
    334        
     302        ht->exit = texit;
    335303        process_pending_wait();
    336         hash_table_remove(&task_hash_table, &id);
    337        
    338         return EOK;
     304
     305        // W lock
     306        hash_table_remove_item(&task_hash_table, &ht->link);
     307        // W unlock
    339308}
    340309
  • uspace/srv/taskman/task.h

    r70d28e8 r62273d1  
    4444extern int task_set_retval(ipc_call_t *);
    4545
    46 extern int ns_task_id_intro(ipc_call_t *);
    47 extern int ns_task_disconnect(ipc_call_t *);
    48 
     46extern int task_id_intro(ipc_call_t *);
     47extern void task_terminated(task_id_t, task_exit_t);
    4948
    5049#endif
Note: See TracChangeset for help on using the changeset viewer.