Changeset dba056b in mainline for uspace/srv/sysman/job.c
- Timestamp:
- 2019-08-06T19:23:56Z (6 years ago)
- Children:
- c6d87c10
- Parents:
- 3f05ef7
- git-author:
- Michal Koutný <xm.koutny+hos@…> (2015-06-20 01:04:31)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-06 19:23:56)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/sysman/job.c
r3f05ef7 rdba056b 80 80 assert(job); 81 81 assert(u); 82 assert(u->job == NULL);83 82 memset(job, 0, sizeof(*job)); 84 83 … … 178 177 } 179 178 179 /** Add multiple references to job 180 * 181 * Non-atomicity doesn't mind as long as individual increments are atomic. 182 * 183 * @note Function is not exported as other modules shouldn't need it. 184 */ 185 static inline void job_add_refs(job_t *job, size_t refs) 186 { 187 for (size_t i = 0; i < refs; ++i) { 188 job_add_ref(job); 189 } 190 } 191 192 /** Delete multiple references to job 193 * 194 * Behavior of concurrent runs with job_add_refs aren't specified. 195 */ 196 static inline void job_del_refs(job_t **job_ptr, size_t refs) 197 { 198 for (size_t i = 0; i < refs; ++i) { 199 job_del_ref(job_ptr); 200 } 201 } 202 180 203 /** Merge two jobs together 181 204 * … … 212 235 trunk->blocked_jobs_count = other->blocked_jobs.size; 213 236 214 /* All allocation is done in job_pre_merge, cannot fail here. */ 237 /* 238 * Note, the sysman_move_observers cannot fail here sice all necessary 239 * allocation is done in job_pre_merge. 240 */ 241 size_t observers_refs = sysman_observers_count(other); 215 242 int rc = sysman_move_observers(other, trunk); 216 243 assert(rc == EOK); 244 245 /* When we move observers, don't forget to pass their references too. */ 246 job_add_refs(trunk, observers_refs); 247 job_del_refs(&other, observers_refs); 217 248 } 218 249 … … 233 264 } 234 265 266 /** Consistenly add jobs to the queue 267 * 268 * @param[in/out] closure jobs closure, on success it's emptied, otherwise 269 * you should take care of remaining jobs 270 * 271 * @return EOK on success 272 * @return EBUSY when any job in closure is conflicting 273 */ 235 274 int job_queue_add_closure(dyn_array_t *closure) 236 275 { … … 307 346 308 347 unit_t *u = job->unit; 309 assert(u->bfs_job != NULL);310 348 assert(u->job == NULL); 311 u->job = u->bfs_job;312 u-> bfs_job = NULL;313 314 349 /* Pass reference from the closure to the unit */ 350 u->job = job; 351 352 /* Enqueue job (new reference) */ 315 353 job->state = JOB_PENDING; 316 /* We pass reference from the closure to the queue */354 job_add_ref(job); 317 355 list_append(&job->job_queue, &job_queue); 318 356 } 357 358 /* We've stolen references from the closure, so erase it */ 359 dyn_array_clear(closure); 319 360 320 361 return EOK; … … 347 388 /* Check invariant */ 348 389 list_foreach(units, units, unit_t, u) { 349 assert(u->bfs_job == false);390 assert(u->bfs_job == NULL); 350 391 } 351 392 … … 390 431 } 391 432 } 392 // sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit)); 393 // dyn_array_foreach(*job_closure, job_t *, job_it) { 394 // sysman_log(LVL_DEBUG2, "%s\t%s", __func__, unit_name((*job_it)->unit)); 395 // } 433 sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit)); 434 dyn_array_foreach(*job_closure, job_t *, job_it) { 435 sysman_log(LVL_DEBUG2, "%s\t%s, refs: %u", __func__, 436 unit_name((*job_it)->unit), atomic_get(&(*job_it)->refcnt)); 437 } 396 438 rc = EOK; 397 439 … … 402 444 job_del_ref(&u->bfs_job); 403 445 list_remove(cur_link); 446 } 447 448 /* Clean after ourselves (BFS tag jobs) */ 449 dyn_array_foreach(*job_closure, job_t *, job_it) { 450 assert(*job_it == (*job_it)->unit->bfs_job); 451 job_del_ref(&(*job_it)->unit->bfs_job); 452 (*job_it)->unit->bfs_job = NULL; 404 453 } 405 454 … … 514 563 assert(job->state != JOB_FINISHED); 515 564 assert(job->retval != JOB_UNDEFINED_); 516 assert(job->unit->job == job); 517 518 sysman_log(LVL_DEBUG2, "%s(%p) %s ret %i", 519 __func__, job, unit_name(job->unit), job->retval); 565 assert(!job->unit->job || job->unit->job == job); 566 567 sysman_log(LVL_DEBUG2, "%s(%p) %s ret %i, ref %i", 568 __func__, job, unit_name(job->unit), job->retval, 569 atomic_get(&job->refcnt)); 520 570 521 571 job->state = JOB_FINISHED; … … 528 578 dyn_array_clear(&job->blocked_jobs); 529 579 530 /* 531 * Remove job from unit and pass the reference from the unit to the 532 * event. 533 */ 534 job->unit->job = NULL; 580 /* Add reference for event handler */ 581 if (job->unit->job == NULL) { 582 job_add_ref(job); 583 } else { 584 /* Pass reference from unit */ 585 job->unit->job = NULL; 586 } 535 587 sysman_raise_event(&sysman_event_job_finished, job); 536 588 }
Note:
See TracChangeset
for help on using the changeset viewer.