Changeset 8ed1b18 in rtems-libbsd


Ignore:
Timestamp:
Feb 17, 2015, 7:49:10 PM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, c1e05b9ea378b2971e3d7704779112b4bc4296da, freebsd-9.3, 4a77611a223ea883fb548679b516d326a020d447
Children:
e5db084
Parents:
e5a0175
git-author:
Sebastian Huber <sebastian.huber@…> (02/17/15 19:49:10)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/06/15 13:58:13)
Message:

rtems_bsd_mutex: SMP support via ISR locks

Location:
rtemsbsd
Files:
3 edited

Legend:

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

    re5a0175 r8ed1b18  
    88
    99/*
    10  * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2014, 2015 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    4141#define _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEX_H_
    4242
     43#include <rtems/score/isrlock.h>
    4344#include <rtems/score/rbtree.h>
    4445#include <rtems/score/thread.h>
     
    4950
    5051typedef struct {
     52        ISR_LOCK_MEMBER(lock)
    5153        Thread_Control *owner;
    5254        int nest_level;
  • rtemsbsd/include/machine/rtems-bsd-muteximpl.h

    re5a0175 r8ed1b18  
    99
    1010/*
    11  * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
     11 * Copyright (c) 2014, 2015 embedded brains GmbH.  All rights reserved.
    1212 *
    1313 *  embedded brains GmbH
     
    4848#include <rtems/bsd/sys/lock.h>
    4949
    50 #include <rtems/score/isrlevel.h>
    5150#include <rtems/score/threadimpl.h>
    52 #include <rtems/score/threadqimpl.h>
    5351
    5452#ifdef __cplusplus
     
    6058    struct lock_class *class, const char *name, const char *type, int flags)
    6159{
     60        _ISR_lock_Initialize(&m->lock, name);
    6261        m->owner = NULL;
    6362        m->nest_level = 0;
     
    6867
    6968void rtems_bsd_mutex_lock_more(struct lock_object *lock, rtems_bsd_mutex *m,
    70     Thread_Control *owner, Thread_Control *executing, ISR_Level level);
     69    Per_CPU_Control *cpu_self, Thread_Control *owner,
     70    Thread_Control *executing, ISR_lock_Context *lock_context);
    7171
    7272static inline void
    7373rtems_bsd_mutex_lock(struct lock_object *lock, rtems_bsd_mutex *m)
    7474{
    75         ISR_Level level;
     75        ISR_lock_Context lock_context;
     76        Per_CPU_Control *cpu_self;
    7677        Thread_Control *executing;
    7778        Thread_Control *owner;
    7879
    79         _ISR_Disable(level);
     80        _ISR_lock_ISR_disable_and_acquire(&m->lock, &lock_context);
    8081
    8182        owner = m->owner;
    82         executing = _Thread_Executing;
     83        cpu_self = _Per_CPU_Get();
     84        executing = cpu_self->executing;
    8385
    8486        if (__predict_true(owner == NULL)) {
     
    8688                ++executing->resource_count;
    8789
    88                 _ISR_Enable(level);
     90                _ISR_lock_Release_and_ISR_enable(&m->lock, &lock_context);
    8991        } else {
    90                 rtems_bsd_mutex_lock_more(lock, m, owner, executing, level);
     92                rtems_bsd_mutex_lock_more(lock, m, cpu_self, owner, executing,
     93                    &lock_context);
    9194        }
    9295}
     
    9699{
    97100        int success;
    98         ISR_Level level;
     101        ISR_lock_Context lock_context;
    99102        Thread_Control *executing;
    100103        Thread_Control *owner;
    101104
    102         _ISR_Disable(level);
     105        _ISR_lock_ISR_disable_and_acquire(&m->lock, &lock_context);
    103106
    104107        owner = m->owner;
     
    117120        }
    118121
    119         _ISR_Enable(level);
     122        _ISR_lock_Release_and_ISR_enable(&m->lock, &lock_context);
    120123
    121124        return (success);
     
    123126
    124127void rtems_bsd_mutex_unlock_more(rtems_bsd_mutex *m, Thread_Control *owner,
    125     int keep_priority, RBTree_Node *first, ISR_Level level);
     128    int keep_priority, RBTree_Node *first, ISR_lock_Context *lock_context);
    126129
    127130static inline void
    128131rtems_bsd_mutex_unlock(rtems_bsd_mutex *m)
    129132{
    130         ISR_Level level;
     133        ISR_lock_Context lock_context;
    131134        int nest_level;
    132135
    133         _ISR_Disable(level);
     136        _ISR_lock_ISR_disable_and_acquire(&m->lock, &lock_context);
    134137
    135138        nest_level = m->nest_level;
     
    139142                int keep_priority;
    140143
     144                BSD_ASSERT(owner == _Thread_Executing);
     145
    141146                --owner->resource_count;
    142147                keep_priority = _Thread_Owns_resources(owner)
     
    145150                m->owner = NULL;
    146151
    147                 if (__predict_true(first == NULL && keep_priority
    148                     && owner == _Thread_Executing)) {
    149                         _ISR_Enable(level);
     152                if (__predict_true(first == NULL && keep_priority)) {
     153                        _ISR_lock_Release_and_ISR_enable(&m->lock, &lock_context);
    150154                } else {
    151155                        rtems_bsd_mutex_unlock_more(m, owner, keep_priority,
    152                             first, level);
     156                            first, &lock_context);
    153157                }
    154158
     
    156160                m->nest_level = nest_level - 1;
    157161
    158                 _ISR_Enable(level);
     162                _ISR_lock_Release_and_ISR_enable(&m->lock, &lock_context);
    159163        }
    160164}
     
    184188        }
    185189
     190        _ISR_lock_Destroy(&m->lock);
    186191        lock_destroy(lock);
    187192}
  • rtemsbsd/rtems/rtems-bsd-muteximpl.c

    re5a0175 r8ed1b18  
    88
    99/*
    10  * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2014, 2015 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    4343#include <rtems/score/schedulerimpl.h>
    4444#include <rtems/score/threaddispatch.h>
     45#include <rtems/score/threadqimpl.h>
     46
     47#define INTEND_TO_BLOCK \
     48    (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK)
     49
     50#define BLOCKED \
     51    (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED)
     52
     53#define INTERRUPT_SATISFIED \
     54    (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED)
    4555
    4656void
    4757rtems_bsd_mutex_lock_more(struct lock_object *lock, rtems_bsd_mutex *m,
    48     Thread_Control *owner, Thread_Control *executing, ISR_Level level)
     58    Per_CPU_Control *cpu_self, Thread_Control *owner,
     59    Thread_Control *executing, ISR_lock_Context *lock_context)
    4960{
    5061        if (owner == executing) {
     
    5263                ++m->nest_level;
    5364
    54                 _ISR_Enable(level);
     65                _ISR_lock_Release_and_ISR_enable(&m->lock, lock_context);
    5566        } else {
     67                bool success;
     68
    5669                _RBTree_Insert(&m->rivals, &executing->RBNode,
    5770                    _Thread_queue_Compare_priority, false);
    5871                ++executing->resource_count;
    5972
    60                 _Thread_Disable_dispatch();
    61                 _ISR_Enable(level);
     73                _Thread_Dispatch_disable_critical(cpu_self);
     74                _Giant_Acquire(cpu_self);
    6275
     76                /* Priority inheritance */
    6377                _Scheduler_Change_priority_if_higher(_Scheduler_Get(owner),
    6478                    owner, executing->current_priority, false);
     79
     80                _Thread_Wait_flags_set(executing, INTEND_TO_BLOCK);
     81
     82                _ISR_lock_Release_and_ISR_enable(&m->lock, lock_context);
     83
    6584                _Thread_Set_state(executing, STATES_WAITING_FOR_MUTEX);
    6685
    67                 _Thread_Enable_dispatch();
     86                success = _Thread_Wait_flags_try_change(executing,
     87                    INTEND_TO_BLOCK, BLOCKED);
     88                if (!success) {
     89                        _Thread_Unblock(executing);
     90                }
     91
     92                _Giant_Release(cpu_self);
     93                _Thread_Dispatch_enable(cpu_self);
    6894        }
    6995}
     
    7197void
    7298rtems_bsd_mutex_unlock_more(rtems_bsd_mutex *m, Thread_Control *owner,
    73     int keep_priority, RBTree_Node *first, ISR_Level level)
     99    int keep_priority, RBTree_Node *first, ISR_lock_Context *lock_context)
    74100{
    75         BSD_ASSERT(owner == _Thread_Executing);
    76 
    77101        if (first != NULL) {
    78102                Thread_Control *new_owner;
     103                bool success;
    79104
    80105                _RBTree_Extract(&m->rivals, first);
     
    83108                m->owner = new_owner;
    84109
    85                 _Thread_Disable_dispatch();
    86                 _ISR_Enable(level);
     110                success = _Thread_Wait_flags_try_change_critical(new_owner,
     111                    INTEND_TO_BLOCK, INTERRUPT_SATISFIED);
     112                if (success) {
     113                        _ISR_lock_Release_and_ISR_enable(&m->lock,
     114                            lock_context);
     115                } else {
     116                        Per_CPU_Control *cpu_self;
    87117
    88                 _Thread_Clear_state(new_owner, STATES_WAITING_FOR_MUTEX);
     118                        cpu_self = _Per_CPU_Get();
     119                        _Thread_Dispatch_disable_critical(cpu_self);
     120                        _ISR_lock_Release_and_ISR_enable(&m->lock,
     121                            lock_context);
     122                        _Giant_Acquire(cpu_self);
    89123
    90                 _Thread_Enable_dispatch();
     124                        _Thread_Unblock(new_owner);
     125
     126                        _Giant_Release(cpu_self);
     127                        _Thread_Dispatch_enable(cpu_self);
     128                }
    91129        } else {
    92                 _ISR_Enable(level);
     130                _ISR_lock_Release_and_ISR_enable(&m->lock, lock_context);
    93131        }
    94132
Note: See TracChangeset for help on using the changeset viewer.