source: mainline/uspace/srv/sysman/job_closure.c@ 92a7cfb1

Last change on this file since 92a7cfb1 was 25a9fec, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

sysman: Refactor job.c into job_queue.c and job_closure.c

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 * Copyright (c) 2015 Michal Koutny
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <adt/list.h>
30#include <assert.h>
31#include <errno.h>
32#include <stdlib.h>
33
34#include "repo.h"
35#include "edge.h"
36#include "job_closure.h"
37#include "log.h"
38
39
40/*
41 * Static functions
42 */
43
44static int job_add_blocked_job(job_t *blocking_job, job_t *blocked_job)
45{
46 assert(blocking_job->blocked_jobs.size ==
47 blocking_job->blocked_jobs_count);
48
49 int rc = dyn_array_append(&blocking_job->blocked_jobs, job_t *,
50 blocked_job);
51 if (rc != EOK) {
52 return ENOMEM;
53 }
54 job_add_ref(blocked_job);
55
56 blocking_job->blocked_jobs_count += 1;
57 blocked_job->blocking_jobs += 1;
58
59 return EOK;
60}
61
62
63/*
64 * Non-static functions
65 */
66int job_create_closure(job_t *main_job, dyn_array_t *job_closure)
67{
68 sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(main_job->unit));
69 int rc;
70 list_t units_fifo;
71 list_initialize(&units_fifo);
72
73 /* Check invariant */
74 list_foreach(units, units, unit_t, u) {
75 assert(u->bfs_job == NULL);
76 }
77
78 unit_t *unit = main_job->unit;
79 job_add_ref(main_job);
80 unit->bfs_job = main_job;
81 list_append(&unit->bfs_link, &units_fifo);
82
83 while (!list_empty(&units_fifo)) {
84 unit = list_get_instance(list_first(&units_fifo), unit_t,
85 bfs_link);
86 list_remove(&unit->bfs_link);
87 job_t *job = unit->bfs_job;
88 assert(job != NULL);
89
90 job_add_ref(job);
91 dyn_array_append(job_closure, job_t *, job);
92
93 /*
94 * Traverse dependencies edges
95 * According to dependency type and edge direction create
96 * appropriate jobs (currently "After" only).
97 */
98 list_foreach(unit->edges_out, edges_out, unit_edge_t, e) {
99 unit_t *u = e->output;
100 job_t *blocking_job;
101
102 if (u->bfs_job == NULL) {
103 blocking_job = job_create(u, job->target_state);
104 if (blocking_job == NULL) {
105 rc = ENOMEM;
106 goto finish;
107 }
108 /* Pass reference to unit */
109 u->bfs_job = blocking_job;
110 list_append(&u->bfs_link, &units_fifo);
111 } else {
112 blocking_job = u->bfs_job;
113 }
114
115 job_add_blocked_job(blocking_job, job);
116 }
117 }
118 sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit));
119 dyn_array_foreach(*job_closure, job_t *, job_it) {
120 sysman_log(LVL_DEBUG2, "%s\t%s, refs: %u", __func__,
121 unit_name((*job_it)->unit), atomic_get(&(*job_it)->refcnt));
122 }
123 rc = EOK;
124
125finish:
126 /* Unreference any jobs in interrupted BFS queue */
127 list_foreach_safe(units_fifo, cur_link, next_link) {
128 unit_t *u = list_get_instance(cur_link, unit_t, bfs_link);
129 job_del_ref(&u->bfs_job);
130 list_remove(cur_link);
131 }
132
133 /* Clean after ourselves (BFS tag jobs) */
134 dyn_array_foreach(*job_closure, job_t *, job_it) {
135 assert(*job_it == (*job_it)->unit->bfs_job);
136 job_del_ref(&(*job_it)->unit->bfs_job);
137 (*job_it)->unit->bfs_job = NULL;
138 }
139
140 return rc;
141}
142
Note: See TracBrowser for help on using the repository browser.