Changeset eae664e in rtems-libbsd


Ignore:
Timestamp:
Mar 12, 2018, 1:38:46 PM (13 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
647dd08ae2aa69b935c2847ea450fb824322ecae, c6261f97870562d4c797cfb1ff1ba0affb85a916
Children:
67c35b9
Parents:
2275776
git-author:
Sebastian Huber <sebastian.huber@…> (03/12/18 13:38:46)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/13/18 10:27:11)
Message:

mutex: Use panic() after ISR lock release

Using panic() with interrupts disabled could lead to an additional error
(INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT) due to a potentially
blocking output.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • rtemsbsd/include/machine/rtems-bsd-muteximpl.h

    r2275776 reae664e  
    99
    1010/*
    11  * Copyright (c) 2014, 2017 embedded brains GmbH.  All rights reserved.
     11 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
    1212 *
    1313 *  embedded brains GmbH
     
    4747#include <sys/types.h>
    4848#include <sys/lock.h>
     49#include <sys/systm.h>
     50
     51#include <inttypes.h>
    4952
    5053#include <rtems/score/threadimpl.h>
     
    161164                success = 1;
    162165        } else if (owner == executing) {
    163                 BSD_ASSERT(lock->lo_flags & LO_RECURSABLE);
     166                if ((lock->lo_flags & LO_RECURSABLE) == 0) {
     167                        rtems_bsd_mutex_release(m, isr_level, &queue_context);
     168                        panic("mutex trylock: %s: not LO_RECURSABLE\n",
     169                            m->queue.Queue.name);
     170                }
     171
    164172                ++m->nest_level;
    165173                success = 1;
     
    179187        Thread_queue_Context queue_context;
    180188        Thread_Control *owner;
     189        Thread_Control *executing;
    181190        int nest_level;
    182191
     
    187196        nest_level = m->nest_level;
    188197        owner = m->queue.Queue.owner;
    189 
    190         BSD_ASSERT(owner == _Thread_Executing);
     198        executing = _Thread_Executing;
     199
     200        if (__predict_false(owner != executing)) {
     201                rtems_bsd_mutex_release(m, isr_level, &queue_context);
     202                panic("mutex unlock: %s: owner 0x%08" PRIx32
     203                    " != executing 0x%08" PRIx32 "\n", m->queue.Queue.name,
     204                    owner->Object.id, executing->Object.id);
     205        }
    191206
    192207        if (__predict_true(nest_level == 0)) {
  • rtemsbsd/rtems/rtems-kernel-muteximpl.c

    r2275776 reae664e  
    88
    99/*
    10  * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    4949{
    5050        if (owner == executing) {
    51                 BSD_ASSERT(lock->lo_flags & LO_RECURSABLE);
     51                if ((lock->lo_flags & LO_RECURSABLE) == 0) {
     52                        _Thread_queue_Release(&m->queue, queue_context);
     53                        panic("mutex lock: %s: not LO_RECURSABLE\n",
     54                            m->queue.Queue.name);
     55                }
     56
    5257                ++m->nest_level;
    53 
    5458                _Thread_queue_Release(&m->queue, queue_context);
    5559        } else {
  • testsuite/mutex01/test_main.c

    r2275776 reae664e  
    11/*
    2  * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    6767        rtems_id worker_task[WORKER_COUNT];
    6868        bool done[WORKER_COUNT];
     69        rtems_id panic_task;
    6970} test_context;
    7071
     
    479480}
    480481
     482#define PANIC_DO_LOCK 0
     483
     484#define PANIC_DO_TRYLOCK 1
     485
     486#define PANIC_DO_UNLOCK 2
     487
     488static void
     489panic_task(rtems_task_argument arg)
     490{
     491        test_context *ctx = &test_instance;
     492        struct mtx *mtx = &ctx->mtx;
     493
     494        switch (arg) {
     495        case PANIC_DO_LOCK:
     496                mtx_lock(mtx);
     497                mtx_lock(mtx);
     498                break;
     499        case PANIC_DO_TRYLOCK:
     500                mtx_lock(mtx);
     501                mtx_trylock(mtx);
     502                break;
     503        case PANIC_DO_UNLOCK:
     504                mtx_unlock(mtx);
     505                break;
     506        default:
     507                assert(0);
     508                break;
     509        }
     510
     511        rtems_task_suspend(RTEMS_SELF);
     512}
     513
     514static void
     515test_mtx_panic(test_context *ctx)
     516{
     517        struct mtx *mtx = &ctx->mtx;
     518        rtems_status_code sc;
     519
     520        puts("test mtx panic");
     521
     522        sc = rtems_task_create(rtems_build_name('P', 'A', 'N', 'I'),
     523            get_self_prio(), RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES,
     524            RTEMS_FLOATING_POINT, &ctx->panic_task);
     525        assert(sc == RTEMS_SUCCESSFUL);
     526
     527        assert(!mtx_initialized(mtx));
     528        mtx_init(mtx, "test", NULL, MTX_DEF);
     529        assert(mtx_initialized(mtx));
     530
     531        /* Lock recursive panic */
     532
     533        sc = rtems_task_start(ctx->panic_task, panic_task, PANIC_DO_LOCK);
     534        assert(sc == RTEMS_SUCCESSFUL);
     535
     536        sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
     537        assert(sc == RTEMS_SUCCESSFUL);
     538
     539        sc = rtems_task_restart(ctx->panic_task, PANIC_DO_UNLOCK);
     540        assert(sc == RTEMS_SUCCESSFUL);
     541
     542        sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
     543        assert(sc == RTEMS_SUCCESSFUL);
     544
     545        /* Try lock recursive panic */
     546
     547        sc = rtems_task_restart(ctx->panic_task, PANIC_DO_TRYLOCK);
     548        assert(sc == RTEMS_SUCCESSFUL);
     549
     550        sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
     551        assert(sc == RTEMS_SUCCESSFUL);
     552
     553        sc = rtems_task_restart(ctx->panic_task, PANIC_DO_UNLOCK);
     554        assert(sc == RTEMS_SUCCESSFUL);
     555
     556        sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
     557        assert(sc == RTEMS_SUCCESSFUL);
     558
     559        /* Unlock not owner panic */
     560
     561        mtx_lock(mtx);
     562
     563        sc = rtems_task_restart(ctx->panic_task, PANIC_DO_UNLOCK);
     564        assert(sc == RTEMS_SUCCESSFUL);
     565
     566        sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
     567        assert(sc == RTEMS_SUCCESSFUL);
     568
     569        mtx_unlock(mtx);
     570
     571        mtx_destroy(mtx);
     572        assert(!mtx_initialized(mtx));
     573
     574        sc = rtems_task_delete(ctx->panic_task);
     575        assert(sc == RTEMS_SUCCESSFUL);
     576}
     577
    481578static void
    482579alloc_basic_resources(void)
     
    505602        test_mtx_trylock(ctx);
    506603        test_mtx_lock(ctx);
     604        test_mtx_panic(ctx);
    507605
    508606        assert(rtems_resource_snapshot_check(&snapshot_1));
Note: See TracChangeset for help on using the changeset viewer.