Changeset 5559712 in mainline for uspace/srv/sysman/job.c


Ignore:
Timestamp:
2019-08-03T09:28:50Z (6 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
c0e4fc50
Parents:
2dda1d4
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-05-07 11:49:47)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-03 09:28:50)
Message:

sysman: Naive autostart instrumentation of locsrv

  • Add IPC_FLAG_AUTOSTART flag.
  • libsysman: sysman's broker and control API.
  • Simple implementation of service unit, exposee verification is missing.
  • Simple mapping of exposee to unit name in locsrv.
  • Temporary debug prints in locsrv.

Conflicts:

boot/Makefile.common
boot/arch/amd64/Makefile.inc
uspace/lib/c/include/ipc/services.h
uspace/srv/locsrv/locsrv.c

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/sysman/job.c

    r2dda1d4 r5559712  
    7373        assert(job);
    7474        assert(u);
     75        memset(job, 0, sizeof(*job));
    7576
    7677        link_initialize(&job->job_queue);
     
    101102                return false;
    102103        }
    103 }
    104 
    105 static bool job_is_runnable(job_t *job)
    106 {
    107         return job->state == JOB_QUEUED && job->blocking_jobs == 0;
    108104}
    109105
     
    126122}
    127123
    128 
    129 
    130 
    131124static void job_destroy(job_t **job_ptr)
    132125{
     
    145138        free(job);
    146139        *job_ptr = NULL;
     140}
     141
     142static bool job_is_runnable(job_t *job)
     143{
     144        return job->state == JOB_QUEUED && job->blocking_jobs == 0;
     145}
     146
     147/** Pop next runnable job
     148 *
     149 * @return runnable job or NULL when there's none
     150 */
     151static job_t *job_queue_pop_runnable(void)
     152{
     153        job_t *result = NULL;
     154
     155        /* Select first runnable job */
     156        list_foreach(job_queue, job_queue, job_t, candidate) {
     157                if (job_is_runnable(candidate)) {
     158                        result = candidate;
     159                        break;
     160                }
     161        }
     162        if (result) {
     163                /* Remove job from queue and pass reference to caller */
     164                list_remove(&result->job_queue);
     165                result->state = JOB_DEQUEUED;
     166        }
     167
     168        return result;
    147169}
    148170
     
    163185                        /*
    164186                         * Currently we have strict strategy not permitting
    165                          * multiple jobs for one unit in the queue.
     187                         * multiple jobs for one unit in the queue at a time.
    166188                         */
    167189                        if ((*new_job_it)->unit == queued_job->unit) {
    168190                                sysman_log(LVL_ERROR,
    169                                     "Cannot queue multiple jobs foor unit '%s'",
     191                                    "Cannot queue multiple jobs for unit '%s'",
    170192                                    unit_name((*new_job_it)->unit));
    171193                                return EEXIST;
     
    184206}
    185207
    186 /** Pop next runnable job
    187  *
    188  * @return runnable job or NULL when there's none
    189  */
    190 job_t *job_queue_pop_runnable(void)
    191 {
    192         job_t *result = NULL;
    193         link_t *first_link = list_first(&job_queue);
    194         bool first_iteration = true;
    195 
    196         list_foreach_safe(job_queue, cur_link, next_link) {
    197                 result = list_get_instance(cur_link, job_t, job_queue);
    198                 if (job_is_runnable(result)) {
    199                         break;
    200                 } else if (!first_iteration && cur_link == first_link) {
    201                         result = NULL;
    202                         break;
    203                 } else {
    204                         /*
    205                          * We make no assuptions about ordering of jobs in the
    206                          * queue, so just move the job to the end of the queue.
    207                          * If there are exist topologic ordering, eventually
    208                          * jobs will be reordered. Furthermore when if there
    209                          * exists any runnable job, it's always found.
    210                          */
    211                         list_remove(cur_link);
    212                         list_append(cur_link, &job_queue);
    213                 }
    214                 first_iteration = false;
    215         }
    216 
    217         if (result) {
    218                 /* Remove job from queue and pass refernce to caller */
    219                 list_remove(&result->job_queue);
    220                 result->state = JOB_DEQUEUED;
    221         }
    222 
    223         return result;
     208/** Process all jobs that aren't transitively blocked
     209 *
     210 * Job can be blocked either by another job or by an incoming event, that will
     211 * be queued after this job_queue_process call.
     212 *
     213 * TODO Write down rules from where this function can be called, to avoid stack
     214 *      overflow.
     215 */
     216void job_queue_process(void)
     217{
     218        job_t *job;
     219        while ((job = job_queue_pop_runnable())) {
     220                job_run(job);
     221                job_del_ref(&job);
     222        }
    224223}
    225224
     
    242241         */
    243242        fifo_push(jobs_fifo, main_job);
    244         job_t *job;
    245243        job_add_ref(main_job);
    246         while ((job = fifo_pop(jobs_fifo)) != NULL) {
    247                 /* No refcount increase, pass it to the closure */
    248                 dyn_array_append(job_closure, job_ptr_t, job);
     244        while (jobs_fifo.head != jobs_fifo.tail) {
     245                job_t *job = fifo_pop(jobs_fifo);
     246               
     247                // TODO more sophisticated check? (unit that is in transitional
     248                //      state cannot have currently multiple jobs queued)
     249                if (job->target_state == job->unit->state) {
     250                        /*
     251                         * Job would do nothing, finish it on spot.
     252                         * No need to continue BFS search from it.
     253                         */
     254                        job->retval = JOB_OK;
     255                        job_finish(job);
     256                        job_del_ref(&job);
     257                        continue;
     258                } else {
     259                        /* No refcount increase, pass it to the closure */
     260                        dyn_array_append(job_closure, job_ptr_t, job);
     261                }
    249262
    250263                /* Traverse dependencies edges */
     
    379392        /* Add reference for the event */
    380393        job_add_ref(job);
    381         sysman_raise_event(&sysman_event_job_changed, job);
    382 }
    383 
     394        sysman_raise_event(&sysman_event_job_finished, job);
     395}
     396
Note: See TracChangeset for help on using the changeset viewer.