Changeset a879d73 in mainline


Ignore:
Timestamp:
2012-11-23T22:58:42Z (11 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d04e46e
Parents:
29b8138
Message:

urcu: Added sanity test of forceful rcu unlock upon fibril exit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/rcutest/rcutest.c

    r29b8138 ra879d73  
    7474static bool basic_sanity_check(void);
    7575static bool dont_wait_for_new_reader(void);
    76 
     76static bool wait_for_exiting_reader(void);
    7777
    7878static test_desc_t test_desc[] = {
     
    104104                .func = basic_sanity_check,
    105105                .name = "basic-sanity",
    106                 .desc = "Locks/unlocks and syncs in a single fibril, no contention.",
     106                .desc = "Locks/unlocks and syncs in 1 fibril, no contention.",
    107107        },
    108108        {
     
    118118                .func = dont_wait_for_new_reader,
    119119                .name = "ignore-new-r",
    120                 .desc = "Syncs with preexisting reader but ignores new reader.",
     120                .desc = "Syncs with preexisting reader; ignores new reader.",
     121        },
     122        {
     123                .aggregate = false,
     124                .type = T_SANITY,
     125                .func = wait_for_exiting_reader,
     126                .name = "dereg-unlocks",
     127                .desc = "Lets deregister_fibril unlock the reader section.",
    121128        },
    122129        {
     
    269276        bool synching;
    270277        bool synched;
     278        size_t failed;
    271279} one_reader_info_t;
    272280
     
    278286        printf("lock{");
    279287        rcu_read_lock();
     288        rcu_read_lock();
    280289        arg->entered_cs = true;
     290        rcu_read_unlock();
    281291
    282292        printf("r-sleep{");
     
    286296        printf("}");
    287297       
     298        if (arg->synched) {
     299                arg->failed = 1;
     300                printf("Error: rcu_sync exited prematurely.\n");
     301        }
     302       
    288303        arg->exited_cs = true;
    289304        rcu_read_unlock();
     
    318333        memory_barrier();
    319334       
    320         if (!info.exited_cs) {
     335        if (!info.exited_cs || info.failed) {
    321336                printf("Error: rcu_sync() returned before the reader exited its CS.\n");
    322337                /*
     
    334349/*--------------------------------------------------------------------*/
    335350
    336 #define WAIT_STEP_US  1000 * USECS_PER_MS
     351#define WAIT_STEP_US  500 * USECS_PER_MS
    337352
    338353typedef struct two_reader_info {
     
    496511
    497512#undef WAIT_STEP_US
     513
     514/*--------------------------------------------------------------------*/
     515#define WAIT_STEP_US  500 * USECS_PER_MS
     516
     517typedef struct exit_reader_info {
     518        bool entered_cs;
     519        bool exited_cs;
     520        bool synching;
     521        bool synched;
     522} exit_reader_info_t;
     523
     524
     525static int exiting_locked_reader(exit_reader_info_t *arg)
     526{
     527        rcu_register_fibril();
     528       
     529        printf("old-lock{");
     530        rcu_read_lock();
     531        rcu_read_lock();
     532        rcu_read_lock();
     533        arg->entered_cs = true;
     534       
     535        printf("wait-for-sync{");
     536        /* Wait for rcu_sync() to start waiting for us. */
     537        while (!arg->synching) {
     538                async_usleep(WAIT_STEP_US);
     539        }
     540        printf(" }");
     541       
     542        rcu_read_unlock();
     543        printf(" }");
     544
     545        arg->exited_cs = true;
     546        /* Store exited_cs before unlocking reader section in deregister. */
     547        memory_barrier();
     548       
     549        /* Deregister forcefully unlocks the reader section. */
     550        rcu_deregister_fibril();
     551        return 0;
     552}
     553
     554
     555static bool wait_for_exiting_reader(void)
     556{
     557        exit_reader_info_t info = { 0 };
     558       
     559        if (!create_fibril((fibril_func_t) exiting_locked_reader, &info))
     560                return false;
     561       
     562        /* Waits for the preexisting_reader to enter its CS.*/
     563        while (!info.entered_cs) {
     564                async_usleep(WAIT_STEP_US);
     565        }
     566       
     567        assert(!info.exited_cs);
     568       
     569        printf("sync[");
     570        info.synching = true;
     571        rcu_synchronize();
     572        info.synched = true;
     573        printf(" ]\n");
     574       
     575        /* Load info.exited_cs */
     576        memory_barrier();
     577       
     578        if (!info.exited_cs) {
     579                printf("Error: rcu_deregister_fibril did not unlock the CS.\n");
     580                return false;
     581        }       
     582       
     583        return true;
     584}
     585
     586#undef WAIT_STEP_US
     587
     588
    498589/*--------------------------------------------------------------------*/
    499590/*--------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.