Changeset be07995 in mainline
- Timestamp:
- 2019-08-17T13:54:09Z (6 years ago)
- Children:
- 8d74fdd
- Parents:
- 015b147
- git-author:
- Michal Koutný <xm.koutny+hos@…> (2016-01-10 23:36:33)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-17 13:54:09)
- Location:
- uspace/srv/sysman
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/sysman/job_closure.c
r015b147 rbe07995 82 82 /** During visit creates job and appends it to closure 83 83 * 84 * @note Assumes BFS start unit's job is already present in closure! 84 * @note Assumes BFS origin unit's job is already present in the closure on the 85 * last position! 85 86 * 86 87 * @return EOK on success … … 94 95 95 96 if (e == NULL) { 96 assert(u->bfs_data == NULL); 97 if (u->bfs_data != NULL) { 98 goto finish; 99 } 97 100 job_t *first_job = dyn_array_last(closure, job_t *); 98 101 … … 133 136 job_del_ref(&created_job); 134 137 } 138 return rc; 139 } 140 141 static int visit_isolate(unit_t *u, unit_edge_t *e, bfs_ops_t *ops, void *arg) 142 { 143 int rc = EOK; 144 job_t *created_job = NULL; 145 job_closure_t *closure = arg; 146 147 sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(u)); 148 /* 149 * Unit can have starting job from original request or from isolation 150 * BFS with different origin. 151 * 152 * Don't check u->state == STATE_STOPPED, closure is created stateless 153 * and its upon merging procedure to correctly resolve conflicting 154 * jobs. 155 * 156 * If we're at the origin (no BFS incoming edge), create a stop job, 157 * put it to the closure and let propagate as if called the propagate 158 * visitor. 159 */ 160 if (e == NULL && u->bfs_data == NULL) { 161 created_job = job_create(u, STATE_STOPPED); 162 if (created_job == NULL) { 163 rc = ENOMEM; 164 goto finish; 165 } 166 167 /* Pass job reference to closure and add one for unit */ 168 rc = dyn_array_append(closure, job_t *, created_job); 169 if (rc != EOK) { 170 goto finish; 171 } 172 } 173 rc = visit_propagate_job(u, e, ops, closure); 174 175 finish: 176 if (rc != EOK) { 177 job_del_ref(&created_job); 178 } 179 sysman_log(LVL_DEBUG2, "%s(%s) -> %i", __func__, unit_name(u), rc); 135 180 return rc; 136 181 } … … 217 262 } 218 263 219 // TODO bfs_traverse_all 220 264 static int bfs_traverse_all(bfs_ops_t *ops, void *arg) 265 { 266 /* Check invariant */ 267 repo_foreach(u) { 268 assert(u->bfs_tag == false); 269 } 270 int rc = EOK; 271 272 repo_foreach(origin) { 273 sysman_log(LVL_DEBUG2, "%s: %p, %i", __func__, origin, origin->bfs_tag); 274 if (origin->bfs_tag == true) { 275 continue; 276 } 277 rc = bfs_traverse_component_internal(origin, ops, arg); 278 if (rc != EOK) { 279 goto finish; 280 } 281 } 282 283 finish: 284 /* Clean after ourselves (BFS tag jobs) */ 285 repo_foreach(u) { 286 u->bfs_tag = false; 287 } 288 return rc; 289 } 221 290 222 291 /* … … 230 299 * @return EOK on success otherwise propagated error 231 300 */ 232 int job_create_closure(job_t *main_job, job_closure_t *job_closure )301 int job_create_closure(job_t *main_job, job_closure_t *job_closure, int flags) 233 302 { 234 303 sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(main_job->unit)); 235 304 236 static bfs_ops_t ops = { 305 if ((flags & CLOSURE_ISOLATE) && main_job->target_state != STATE_STARTED) { 306 // TODO EINVAL? 307 return ENOTSUP; 308 } 309 310 int rc = dyn_array_append(job_closure, job_t *, main_job); 311 if (rc != EOK) { 312 return rc; 313 } 314 job_add_ref(main_job); /* Add one for the closure */ 315 316 /* Propagate main_job to other (dependent) units */ 317 static bfs_ops_t propagate_ops = { 237 318 .clean = traverse_clean, 238 319 .visit = visit_propagate_job 239 320 }; 240 241 321 switch (main_job->target_state) { 242 322 case STATE_STARTED: 243 ops.direction = BFS_FORWARD;323 propagate_ops.direction = BFS_FORWARD; 244 324 break; 245 325 case STATE_STOPPED: 246 ops.direction = BFS_BACKWARD;326 propagate_ops.direction = BFS_BACKWARD; 247 327 break; 248 328 default: … … 250 330 } 251 331 252 int rc = dyn_array_append(job_closure, job_t *, main_job); 253 if (rc != EOK) { 254 return rc; 255 } 256 job_add_ref(main_job); /* Add one for the closure */ 257 258 rc = bfs_traverse_component(main_job->unit, &ops, job_closure); 332 rc = bfs_traverse_component(main_job->unit, &propagate_ops, job_closure); 333 334 sysman_log(LVL_DEBUG2, "%s: %i&%i", __func__, flags, CLOSURE_ISOLATE); 335 if (flags & CLOSURE_ISOLATE) { 336 static bfs_ops_t isolate_ops = { 337 .direction = BFS_BACKWARD, 338 .clean = traverse_clean, 339 .visit = visit_isolate 340 }; 341 rc = bfs_traverse_all(&isolate_ops, job_closure); 342 } 259 343 260 344 if (rc == EOK) { 261 sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit));262 345 dyn_array_foreach(*job_closure, job_t *, job_it) { 263 346 sysman_log(LVL_DEBUG2, "%s\t%s, refs: %u", __func__, -
uspace/srv/sysman/job_closure.h
r015b147 rbe07995 33 33 34 34 #include "job.h" 35 #include "unit.h" 35 36 #define CLOSURE_ISOLATE 0x1 36 37 37 38 typedef dyn_array_t job_closure_t; 38 39 39 extern int job_create_closure(job_t *, job_closure_t * );40 extern int job_create_closure(job_t *, job_closure_t *, int); 40 41 41 42 #endif -
uspace/srv/sysman/repo.c
r015b147 rbe07995 176 176 } 177 177 178 void repo_begin_update _(void) {178 void repo_begin_update(void) { 179 179 sysman_log(LVL_DEBUG2, "%s", __func__); 180 180 fibril_rwlock_write_lock(&repo_lock); … … 293 293 * The function can be safely called from non-event loop fibrils 294 294 */ 295 unit_t *repo_find_unit_by_name _(const char *name)295 unit_t *repo_find_unit_by_name(const char *name) 296 296 { 297 297 return repo_find_unit_by_name_internal(name, true); -
uspace/srv/sysman/sysman.c
r015b147 rbe07995 373 373 free(job_args); 374 374 375 int rc = job_create_closure(job, &job_closure );375 int rc = job_create_closure(job, &job_closure, 0); 376 376 if (rc != EOK) { 377 377 sysman_log(LVL_ERROR, "Cannot create closure for job %p (%i)", -
uspace/srv/sysman/test/job_closure.c
r015b147 rbe07995 32 32 33 33 #include "../job_closure.h" 34 #include "../repo.h" 34 35 35 36 #include "mock_unit.h" … … 50 51 { 51 52 if (expected->size != actual->size) { 52 printf("%s: |expected| - |actual| =%u\n",53 __func__, expected->size -actual->size);53 printf("%s: |expected|, |actual| = %u, %u\n", 54 __func__, expected->size, actual->size); 54 55 return false; 55 56 } … … 119 120 rc = dyn_array_reserve(&act_closure, MAX_TYPES * MAX_UNITS); 120 121 assert(rc == EOK); 122 123 repo_init(); 121 124 } 122 125 … … 148 151 assert(main_job); 149 152 150 int rc = job_create_closure(main_job, &act_closure );153 int rc = job_create_closure(main_job, &act_closure, 0); 151 154 PCUT_ASSERT_INT_EQUALS(EOK, rc); 152 155 … … 179 182 assert(main_job); 180 183 181 int rc = job_create_closure(main_job, &act_closure );184 int rc = job_create_closure(main_job, &act_closure, 0); 182 185 PCUT_ASSERT_INT_EQUALS(EOK, rc); 183 186 … … 212 215 assert(main_job); 213 216 214 int rc = job_create_closure(main_job, &act_closure );217 int rc = job_create_closure(main_job, &act_closure, 0); 215 218 PCUT_ASSERT_INT_EQUALS(EOK, rc); 216 219 … … 227 230 } 228 231 232 PCUT_TEST(job_closure_isolate_linears) { 233 unit_t *u0 = mock_units[UNIT_SERVICE][0]; 234 unit_t *u1 = mock_units[UNIT_SERVICE][1]; 235 unit_t *u2 = mock_units[UNIT_SERVICE][2]; 236 unit_t *u3 = mock_units[UNIT_SERVICE][3]; 237 unit_t *u4 = mock_units[UNIT_SERVICE][4]; 238 unit_t *u5 = mock_units[UNIT_SERVICE][5]; 239 unit_t *u6 = mock_units[UNIT_SERVICE][6]; 240 repo_begin_update(); 241 for (int i = 0; i < 7; ++i) { 242 repo_add_unit(mock_units[UNIT_SERVICE][i]); 243 } 244 repo_commit(); 245 246 /* 247 * 248 * u0 -> u1 -> u2 249 * 250 * u3 -> u4 -> u5 251 * 252 * u6 253 */ 254 mock_add_edge(u0, u1); 255 mock_add_edge(u1, u2); 256 257 mock_add_edge(u3, u4); 258 mock_add_edge(u4, u5); 259 260 job_t *main_job = job_create(u1, STATE_STARTED); 261 assert(main_job); 262 263 int rc = job_create_closure(main_job, &act_closure, CLOSURE_ISOLATE); 264 PCUT_ASSERT_INT_EQUALS(EOK, rc); 265 266 dyn_array_append(&exp_closure, job_t *, dummy_job(u0, STATE_STOPPED)); 267 dyn_array_append(&exp_closure, job_t *, dummy_job(u1, STATE_STARTED)); 268 dyn_array_append(&exp_closure, job_t *, dummy_job(u2, STATE_STARTED)); 269 dyn_array_append(&exp_closure, job_t *, dummy_job(u3, STATE_STOPPED)); 270 dyn_array_append(&exp_closure, job_t *, dummy_job(u4, STATE_STOPPED)); 271 dyn_array_append(&exp_closure, job_t *, dummy_job(u5, STATE_STOPPED)); 272 dyn_array_append(&exp_closure, job_t *, dummy_job(u6, STATE_STOPPED)); 273 274 dummy_add_closure(&act_closure); 275 276 PCUT_ASSERT_TRUE(same_jobs(&exp_closure, &act_closure)); 277 PCUT_ASSERT_TRUE(job_blocked(u1->job, u2->job)); 278 279 PCUT_ASSERT_TRUE(job_blocked(u5->job, u4->job)); 280 PCUT_ASSERT_TRUE(job_blocked(u4->job, u3->job)); 281 282 PCUT_ASSERT_INT_EQUALS(0, u6->job->blocking_jobs); 283 PCUT_ASSERT_INT_EQUALS(0, u0->job->blocking_jobs); 284 } 229 285 230 286 PCUT_EXPORT(job_closure); -
uspace/srv/sysman/test/mock_unit.h
r015b147 rbe07995 36 36 #include "../unit.h" 37 37 38 #define MAX_UNITS 538 #define MAX_UNITS 7 39 39 #define MAX_TYPES 4 40 40
Note:
See TracChangeset
for help on using the changeset viewer.