Changeset 015b147 in mainline


Ignore:
Timestamp:
2019-08-17T13:52:32Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
be07995
Parents:
31ef7c1
git-author:
Michal Koutný <xm.koutny+hos@…> (2016-01-10 17:17:19)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-17 13:52:32)
Message:

sysman: Refactored unit repo iteration and locking

Location:
uspace/srv/sysman
Files:
6 edited

Legend:

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

    r31ef7c1 r015b147  
    197197        size_t total = 0;
    198198        repo_rlock();
    199         list_foreach(units, units, unit_t, u) {
     199        repo_foreach(u) {
    200200                if (filled < to_fill) {
    201201                        buffer[filled++] = u->handle;
  • uspace/srv/sysman/job_closure.c

    r31ef7c1 r015b147  
    205205{
    206206        /* Check invariant */
    207         list_foreach(units, units, unit_t, u) {
     207        repo_foreach(u) {
    208208                assert(u->bfs_tag == false);
    209209        }
     
    211211
    212212        /* Clean after ourselves (BFS tag jobs) */
    213         list_foreach(units, units, unit_t, u) {
     213        repo_foreach(u) {
    214214                u->bfs_tag = false;
    215215        }
  • uspace/srv/sysman/repo.c

    r31ef7c1 r015b147  
    3838#include "log.h"
    3939
    40 LIST_INITIALIZE(units);
     40LIST_INITIALIZE(units_);
    4141
    4242static hash_table_t units_by_name;
     
    119119static void repo_remove_unit_internal(unit_t *u)
    120120{
     121        assert(fibril_rwlock_is_write_locked(&repo_lock));
     122
    121123        hash_table_remove_item(&units_by_name, &u->units_by_name);
    122124        hash_table_remove_item(&units_by_handle, &u->units_by_handle);
     
    125127        // TODO decrease refcount of unit
    126128        // unit may be referenced e.g. from running job, thus we cannot simply destroy it
     129}
     130
     131static unit_t *repo_find_unit_by_name_internal(const char *name, bool lock)
     132{
     133        sysman_log(LVL_DEBUG2, "%s(%s, %i)", __func__, name, lock);
     134        if (lock) fibril_rwlock_read_lock(&repo_lock);
     135        ht_link_t *ht_link = hash_table_find(&units_by_name, (void *)name);
     136        if (lock) fibril_rwlock_read_unlock(&repo_lock);
     137
     138        if (ht_link != NULL) {
     139                return hash_table_get_inst(ht_link, unit_t, units_by_name);
     140        } else {
     141                return NULL;
     142        }
    127143}
    128144
     
    139155        assert(unit->handle == 0);
    140156        assert(unit->name != NULL);
     157        assert(fibril_rwlock_is_write_locked(&repo_lock));
    141158        sysman_log(LVL_DEBUG2, "%s('%s')", __func__, unit_name(unit));
    142159
    143         fibril_rwlock_write_lock(&repo_lock);
    144160        if (hash_table_insert_unique(&units_by_name, &unit->units_by_name)) {
    145161                /* Pointers are same size as unit_handle_t both on 32b and 64b */
     
    147163
    148164                hash_table_insert(&units_by_handle, &unit->units_by_handle);
    149                 list_append(&unit->units, &units);
    150                 fibril_rwlock_write_unlock(&repo_lock);
     165                list_append(&unit->units, &units_);
    151166                return EOK;
    152167        } else {
    153                 fibril_rwlock_write_unlock(&repo_lock);
    154168                return EEXISTS;
    155169        }
     
    162176}
    163177
    164 void repo_begin_update(void) {
    165         sysman_log(LVL_DEBUG2, "%s", __func__);
     178void repo_begin_update_(void) {
     179        sysman_log(LVL_DEBUG2, "%s", __func__);
     180        fibril_rwlock_write_lock(&repo_lock);
    166181}
    167182
     
    196211         */
    197212        hash_table_apply(&units_by_name, &repo_commit_unit, NULL);
     213        fibril_rwlock_write_unlock(&repo_lock);
    198214}
    199215
     
    228244
    229245        hash_table_apply(&units_by_name, &repo_rollback_unit, NULL);
     246        fibril_rwlock_write_unlock(&repo_lock);
    230247}
    231248
     
    243260
    244261                unit_t *output =
    245                     repo_find_unit_by_name(e->output_name);
     262                    repo_find_unit_by_name_unsafe(e->output_name);
    246263                if (output == NULL) {
    247264                        sysman_log(LVL_ERROR,
     
    273290}
    274291
    275 unit_t *repo_find_unit_by_name(const char *name)
    276 {
    277         fibril_rwlock_read_lock(&repo_lock);
    278         ht_link_t *ht_link = hash_table_find(&units_by_name, (void *)name);
    279         fibril_rwlock_read_unlock(&repo_lock);
    280 
    281         if (ht_link != NULL) {
    282                 return hash_table_get_inst(ht_link, unit_t, units_by_name);
    283         } else {
    284                 return NULL;
    285         }
    286 }
    287 
     292/**
     293 * The function can be safely called from non-event loop fibrils
     294 */
     295unit_t *repo_find_unit_by_name_(const char *name)
     296{
     297        return repo_find_unit_by_name_internal(name, true);
     298}
     299
     300/**
     301 * @note Caller must hold repo_lock (at least reader)
     302 */
     303unit_t *repo_find_unit_by_name_unsafe(const char *name)
     304{
     305        return repo_find_unit_by_name_internal(name, false);
     306}
     307
     308/**
     309 * The function can be safely called from non-event loop fibrils
     310 */
    288311unit_t *repo_find_unit_by_handle(unit_handle_t handle)
    289312{
     313        sysman_log(LVL_DEBUG2, "%s", __func__);
    290314        fibril_rwlock_read_lock(&repo_lock);
    291315        ht_link_t *ht_link = hash_table_find(&units_by_handle, &handle);
     
    301325void repo_rlock(void)
    302326{
     327        sysman_log(LVL_DEBUG2, "%s", __func__);
    303328        fibril_rwlock_read_lock(&repo_lock);
    304329}
     
    306331void repo_runlock(void)
    307332{
     333        sysman_log(LVL_DEBUG2, "%s", __func__);
    308334        fibril_rwlock_read_unlock(&repo_lock);
    309335}
  • uspace/srv/sysman/repo.h

    r31ef7c1 r015b147  
    3838#define ANONYMOUS_SERVICE_MASK "service_%" PRIu64
    3939
    40 /*
    41  * If you access units out of the main event-loop fibril call repo_rlock(),
    42  * repo_runlock().
     40/**
     41 * Don't access this structure directly, use repo_foreach instead.
    4342 */
    44 extern list_t units;
     43extern list_t units_;
     44
     45/**
     46 * If you iterate units out of the main event-loop fibril, wrap the foreach
     47 * into repo_rlock() and repo_runlock().
     48 *
     49 * @param  it  name of unit_t * loop iterator variable
     50 */
     51#define repo_foreach(_it) \
     52        list_foreach(units_, units, unit_t, _it)
     53
     54/**
     55 * @see repo_foreach
     56 *
     57 * @param type  unit_type_t  restrict to units of type only
     58 * @param it                 name of unit_t * loop iterator variable
     59 */
     60#define repo_foreach_t(_type, _it) \
     61        list_foreach(units_, units, unit_t, _it) \
     62                if (_it->type == (_type))
    4563
    4664extern void repo_init(void);
     
    5876
    5977extern unit_t *repo_find_unit_by_name(const char *);
     78extern unit_t *repo_find_unit_by_name_unsafe(const char *);
    6079extern unit_t *repo_find_unit_by_handle(unit_handle_t);
    6180
  • uspace/srv/sysman/sm_task.c

    r31ef7c1 r015b147  
    7575         * instead of specialized structures.
    7676         */
    77         list_foreach(units, units, unit_t, u) {
    78                 if (u->type != UNIT_SERVICE) {
    79                         continue;
    80                 }
     77        repo_foreach_t(UNIT_SERVICE, u) {
    8178                if (CAST_SVC(u)->main_task_id == tid) {
    8279                        return CAST_SVC(u);
  • uspace/srv/sysman/units/unit_cfg.c

    r31ef7c1 r015b147  
    8282        }
    8383       
    84         unit_t *u = repo_find_unit_by_name(unit_name);
     84        /* We parse files as part of ongoing repo transaction (locked). */
     85        unit_t *u = repo_find_unit_by_name_unsafe(unit_name);
    8586        if (u != NULL) {
    8687                // TODO allow updating configuration of existing unit
Note: See TracChangeset for help on using the changeset viewer.