mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-17 08:25:39 +08:00
Replace RTEMS objects with custom implementation
Performance analysis revealed that the standard RTEMS objects are a major bottleneck. The object get mechanism and attribute checks at runtime have a significant overhead. Use a custom implementation for synchronization primitives. This drops also the size of the synchronization primitives considerably.
This commit is contained in:
60
rtemsbsd/include/machine/rtems-bsd-mutex.h
Normal file
60
rtemsbsd/include/machine/rtems-bsd-mutex.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup rtems_bsd_machine
|
||||
*
|
||||
* @brief TODO.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEX_H_
|
||||
#define _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEX_H_
|
||||
|
||||
#include <rtems/score/rbtree.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
Thread_Control *owner;
|
||||
int nest_level;
|
||||
RBTree_Control rivals;
|
||||
} rtems_bsd_mutex;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEX_H_ */
|
220
rtemsbsd/include/machine/rtems-bsd-muteximpl.h
Normal file
220
rtemsbsd/include/machine/rtems-bsd-muteximpl.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup rtems_bsd_machine
|
||||
*
|
||||
* @brief Implementation of a mutex with a simple priority inheritance
|
||||
* protocol.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEXIMPL_H_
|
||||
#define _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEXIMPL_H_
|
||||
|
||||
#include <machine/rtems-bsd-mutex.h>
|
||||
#include <machine/rtems-bsd-support.h>
|
||||
|
||||
#include <rtems/bsd/sys/types.h>
|
||||
#include <rtems/bsd/sys/lock.h>
|
||||
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/rbtreeimpl.h>
|
||||
#include <rtems/score/schedulerimpl.h>
|
||||
#include <rtems/score/threaddispatch.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
static inline void
|
||||
rtems_bsd_mutex_init(struct lock_object *lock, rtems_bsd_mutex *m,
|
||||
struct lock_class *class, const char *name, const char *type, int flags)
|
||||
{
|
||||
m->owner = NULL;
|
||||
m->nest_level = 0;
|
||||
_RBTree_Initialize_empty(&m->rivals);
|
||||
|
||||
lock_init(lock, class, name, type, flags);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtems_bsd_mutex_lock(struct lock_object *lock, rtems_bsd_mutex *m)
|
||||
{
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
Thread_Control *owner;
|
||||
|
||||
_ISR_Disable(level);
|
||||
|
||||
owner = m->owner;
|
||||
executing = _Thread_Executing;
|
||||
|
||||
if (owner == NULL) {
|
||||
m->owner = executing;
|
||||
++executing->resource_count;
|
||||
|
||||
_ISR_Enable(level);
|
||||
} else if (owner == executing) {
|
||||
BSD_ASSERT(lock->lo_flags & LO_RECURSABLE);
|
||||
++m->nest_level;
|
||||
|
||||
_ISR_Enable(level);
|
||||
} else {
|
||||
_RBTree_Insert(&m->rivals, &executing->RBNode,
|
||||
_Thread_queue_Compare_priority, false);
|
||||
++executing->resource_count;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
_ISR_Enable(level);
|
||||
|
||||
_Scheduler_Change_priority_if_higher(_Scheduler_Get(owner),
|
||||
owner, executing->current_priority, false);
|
||||
_Thread_Set_state(executing, STATES_WAITING_FOR_MUTEX);
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
rtems_bsd_mutex_trylock(struct lock_object *lock, rtems_bsd_mutex *m)
|
||||
{
|
||||
int success;
|
||||
ISR_Level level;
|
||||
Thread_Control *executing;
|
||||
Thread_Control *owner;
|
||||
|
||||
_ISR_Disable(level);
|
||||
|
||||
owner = m->owner;
|
||||
executing = _Thread_Executing;
|
||||
|
||||
if (owner == NULL) {
|
||||
m->owner = executing;
|
||||
++executing->resource_count;
|
||||
success = 1;
|
||||
} else if (owner == executing) {
|
||||
BSD_ASSERT(lock->lo_flags & LO_RECURSABLE);
|
||||
++m->nest_level;
|
||||
success = 1;
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
|
||||
_ISR_Enable(level);
|
||||
|
||||
return (success);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtems_bsd_mutex_unlock(rtems_bsd_mutex *m)
|
||||
{
|
||||
ISR_Level level;
|
||||
int nest_level;
|
||||
|
||||
_ISR_Disable(level);
|
||||
|
||||
nest_level = m->nest_level;
|
||||
if (nest_level != 0) {
|
||||
m->nest_level = nest_level - 1;
|
||||
|
||||
_ISR_Enable(level);
|
||||
} else {
|
||||
RBTree_Node *first;
|
||||
Thread_Control *owner = m->owner;
|
||||
|
||||
BSD_ASSERT(owner == _Thread_Executing);
|
||||
--owner->resource_count;
|
||||
|
||||
first = _RBTree_Get(&m->rivals, RBT_LEFT);
|
||||
|
||||
if (first == NULL) {
|
||||
m->owner = NULL;
|
||||
|
||||
_ISR_Enable(level);
|
||||
} else {
|
||||
Thread_Control *new_owner =
|
||||
THREAD_RBTREE_NODE_TO_THREAD(first);
|
||||
|
||||
m->owner = new_owner;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
_ISR_Enable(level);
|
||||
|
||||
_Thread_Clear_state(new_owner, STATES_WAITING_FOR_MUTEX);
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
if (!_Thread_Owns_resources(owner)
|
||||
&& owner->real_priority != owner->current_priority) {
|
||||
_Thread_Disable_dispatch();
|
||||
_Thread_Change_priority(owner, owner->real_priority, true);
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
rtems_bsd_mutex_owned(rtems_bsd_mutex *m)
|
||||
{
|
||||
|
||||
return (m->owner == _Thread_Get_executing());
|
||||
}
|
||||
|
||||
static inline int
|
||||
rtems_bsd_mutex_recursed(rtems_bsd_mutex *m)
|
||||
{
|
||||
|
||||
return (m->nest_level);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtems_bsd_mutex_destroy(struct lock_object *lock, rtems_bsd_mutex *m)
|
||||
{
|
||||
BSD_ASSERT(_RBTree_Is_empty(&m->rivals));
|
||||
|
||||
if (rtems_bsd_mutex_owned(m)) {
|
||||
m->nest_level = 0;
|
||||
rtems_bsd_mutex_unlock(m);
|
||||
}
|
||||
|
||||
lock_destroy(lock);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_MUTEXIMPL_H_ */
|
@@ -42,8 +42,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <rtems/chain.h>
|
||||
|
||||
/* Debug */
|
||||
|
||||
#define BSD_PRINTF(fmt, ...) printf("%s: " fmt, __func__, ##__VA_ARGS__)
|
||||
@@ -54,16 +52,4 @@
|
||||
|
||||
#define BSD_ASSERT_RV(rv) BSD_ASSERT((rv) == 0)
|
||||
|
||||
extern rtems_chain_control rtems_bsd_lock_chain;
|
||||
|
||||
extern rtems_chain_control rtems_bsd_mtx_chain;
|
||||
|
||||
extern rtems_chain_control rtems_bsd_sx_chain;
|
||||
|
||||
extern rtems_chain_control rtems_bsd_condvar_chain;
|
||||
|
||||
extern rtems_chain_control rtems_bsd_callout_chain;
|
||||
|
||||
extern rtems_chain_control rtems_bsd_malloc_chain;
|
||||
|
||||
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_SUPPORT_H_ */
|
||||
|
@@ -39,153 +39,127 @@
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
#include <machine/rtems-bsd-support.h>
|
||||
|
||||
#include <rtems/score/objectimpl.h>
|
||||
#include <rtems/score/threaddispatch.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
#include <rtems/posix/condimpl.h>
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <rtems/bsd/sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <rtems/bsd/sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_condvar_chain);
|
||||
#include <sys/mutex.h>
|
||||
|
||||
void
|
||||
cv_init(struct cv *cv, const char *desc)
|
||||
{
|
||||
int rv = pthread_cond_init(&cv->cv_id, NULL);
|
||||
|
||||
BSD_ASSERT_RV(rv);
|
||||
|
||||
cv->cv_description = desc;
|
||||
|
||||
rtems_chain_append(&rtems_bsd_condvar_chain, &cv->cv_node);
|
||||
_Thread_queue_Initialize(&cv->cv_waiters, THREAD_QUEUE_DISCIPLINE_PRIORITY,
|
||||
STATES_WAITING_FOR_CONDITION_VARIABLE, EWOULDBLOCK);
|
||||
}
|
||||
|
||||
void
|
||||
cv_destroy(struct cv *cv)
|
||||
{
|
||||
int rv = pthread_cond_destroy(&cv->cv_id);
|
||||
|
||||
BSD_ASSERT_RV(rv);
|
||||
|
||||
rtems_chain_extract(&cv->cv_node);
|
||||
BSD_ASSERT(_Thread_queue_First(&cv->cv_waiters) == NULL);
|
||||
}
|
||||
|
||||
static int _cv_wait_support(struct cv *cv, struct lock_object *lock, int timo, bool relock)
|
||||
static int
|
||||
_cv_wait_support(struct cv *cv, struct lock_object *lock, Watchdog_Interval timo, bool relock)
|
||||
{
|
||||
int eno = 0;
|
||||
Objects_Locations location = OBJECTS_ERROR;
|
||||
POSIX_Condition_variables_Control *pcv = _POSIX_Condition_variables_Get(&cv->cv_id, &location);
|
||||
int error;
|
||||
struct lock_class *class;
|
||||
int lock_state;
|
||||
Thread_Control *executing;
|
||||
|
||||
if (location == OBJECTS_LOCAL) {
|
||||
struct lock_class *class = LOCK_CLASS(lock);
|
||||
int lock_state;
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
if (pcv->Mutex != POSIX_CONDITION_VARIABLES_NO_MUTEX && pcv->Mutex != lock->lo_id) {
|
||||
_Thread_Enable_dispatch();
|
||||
class = LOCK_CLASS(lock);
|
||||
lock_state = (*class->lc_unlock)(lock);
|
||||
|
||||
BSD_ASSERT(false);
|
||||
_Thread_queue_Enter_critical_section(&cv->cv_waiters);
|
||||
|
||||
return EINVAL;
|
||||
}
|
||||
executing = _Thread_Executing;
|
||||
executing->Wait.return_code = 0;
|
||||
executing->Wait.queue = &cv->cv_waiters;
|
||||
|
||||
lock_state = (*class->lc_unlock)(lock);
|
||||
_Thread_queue_Enqueue(&cv->cv_waiters, executing, timo);
|
||||
|
||||
pcv->Mutex = lock->lo_id;
|
||||
DROP_GIANT();
|
||||
|
||||
_Thread_queue_Enter_critical_section(&pcv->Wait_queue);
|
||||
_Thread_Executing->Wait.return_code = 0;
|
||||
_Thread_Executing->Wait.queue = &pcv->Wait_queue;
|
||||
_Thread_Executing->Wait.id = cv->cv_id;
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
/* FIXME: Integer conversion */
|
||||
_Thread_queue_Enqueue(&pcv->Wait_queue, _Thread_Executing, (Watchdog_Interval) timo);
|
||||
PICKUP_GIANT();
|
||||
|
||||
DROP_GIANT();
|
||||
error = (int)executing->Wait.return_code;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
PICKUP_GIANT();
|
||||
|
||||
eno = (int) _Thread_Executing->Wait.return_code;
|
||||
if (eno != 0) {
|
||||
if (eno == ETIMEDOUT) {
|
||||
eno = EWOULDBLOCK;
|
||||
} else {
|
||||
BSD_ASSERT(false);
|
||||
|
||||
eno = EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (relock) {
|
||||
(*class->lc_lock)(lock, lock_state);
|
||||
}
|
||||
|
||||
return eno;
|
||||
if (relock) {
|
||||
(*class->lc_lock)(lock, lock_state);
|
||||
}
|
||||
|
||||
BSD_PANIC("unexpected object location");
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
_cv_wait(struct cv *cv, struct lock_object *lock)
|
||||
{
|
||||
|
||||
_cv_wait_support(cv, lock, 0, true);
|
||||
}
|
||||
|
||||
void
|
||||
_cv_wait_unlock(struct cv *cv, struct lock_object *lock)
|
||||
{
|
||||
|
||||
_cv_wait_support(cv, lock, 0, false);
|
||||
}
|
||||
|
||||
int
|
||||
_cv_timedwait(struct cv *cv, struct lock_object *lock, int timo)
|
||||
{
|
||||
if (timo <= 0) {
|
||||
if (timo <= 0)
|
||||
timo = 1;
|
||||
}
|
||||
|
||||
return _cv_wait_support(cv, lock, timo, true);
|
||||
return (_cv_wait_support(cv, lock, (Watchdog_Interval)timo, true));
|
||||
}
|
||||
|
||||
void
|
||||
cv_signal(struct cv *cv)
|
||||
{
|
||||
int rv = pthread_cond_signal(&cv->cv_id);
|
||||
|
||||
BSD_ASSERT_RV(rv);
|
||||
_Thread_Disable_dispatch();
|
||||
_Thread_queue_Dequeue(&cv->cv_waiters);
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
void
|
||||
cv_broadcastpri(struct cv *cv, int pri)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
/* FIXME: What to do with "pri"? */
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
rv = pthread_cond_broadcast(&cv->cv_id);
|
||||
BSD_ASSERT_RV(rv);
|
||||
}
|
||||
int
|
||||
_cv_wait_sig(struct cv *cvp, struct lock_object *lock)
|
||||
{
|
||||
/* XXX */
|
||||
return _cv_wait_support(cvp, lock, 0, true);
|
||||
}
|
||||
|
||||
int
|
||||
_cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo)
|
||||
{
|
||||
/* XXX */
|
||||
if (timo <= 0) {
|
||||
timo = 1;
|
||||
while (_Thread_queue_Dequeue(&cv->cv_waiters) != NULL) {
|
||||
/* Again */
|
||||
}
|
||||
|
||||
return _cv_wait_support(cvp, lock, timo, true);
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
int
|
||||
_cv_wait_sig(struct cv *cv, struct lock_object *lock)
|
||||
{
|
||||
|
||||
return (_cv_wait_support(cv, lock, 0, true));
|
||||
}
|
||||
|
||||
int
|
||||
_cv_timedwait_sig(struct cv *cv, struct lock_object *lock, int timo)
|
||||
{
|
||||
|
||||
if (timo <= 0)
|
||||
timo = 1;
|
||||
|
||||
return (_cv_wait_support(cv, lock, (Watchdog_Interval)timo, true));
|
||||
}
|
||||
|
@@ -38,12 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
#include <machine/rtems-bsd-thread.h>
|
||||
#include <machine/rtems-bsd-support.h>
|
||||
|
||||
#include <rtems/score/objectimpl.h>
|
||||
#include <rtems/rtems/attrimpl.h>
|
||||
#include <rtems/rtems/semimpl.h>
|
||||
#include <machine/rtems-bsd-muteximpl.h>
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <rtems/bsd/sys/types.h>
|
||||
@@ -59,8 +54,6 @@ static int owner_mtx(struct lock_object *lock, struct thread **owner);
|
||||
#endif
|
||||
static int unlock_mtx(struct lock_object *lock);
|
||||
|
||||
RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_mtx_chain);
|
||||
|
||||
/*
|
||||
* Lock classes for sleep and spin mutexes.
|
||||
*/
|
||||
@@ -103,19 +96,15 @@ assert_mtx(struct lock_object *lock, int what)
|
||||
void
|
||||
lock_mtx(struct lock_object *lock, int how)
|
||||
{
|
||||
|
||||
mtx_lock((struct mtx *)lock);
|
||||
mtx_lock((struct mtx *)lock);
|
||||
}
|
||||
|
||||
int
|
||||
unlock_mtx(struct lock_object *lock)
|
||||
{
|
||||
struct mtx *m;
|
||||
mtx_unlock((struct mtx *)lock);
|
||||
|
||||
m = (struct mtx *)lock;
|
||||
mtx_assert(m, MA_OWNED | MA_NOTRECURSED);
|
||||
mtx_unlock(m);
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,9 +124,6 @@ mtx_init(struct mtx *m, const char *name, const char *type, int opts)
|
||||
{
|
||||
struct lock_class *class;
|
||||
int flags;
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
rtems_id id = RTEMS_ID_NONE;
|
||||
rtems_attribute attr = RTEMS_LOCAL | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY;
|
||||
|
||||
/* Determine lock class and lock flags. */
|
||||
if (opts & MTX_SPIN)
|
||||
@@ -148,55 +134,26 @@ mtx_init(struct mtx *m, const char *name, const char *type, int opts)
|
||||
if (opts & MTX_RECURSE)
|
||||
flags |= LO_RECURSABLE;
|
||||
|
||||
lock_init(&m->lock_object, class, name, type, flags);
|
||||
|
||||
sc = rtems_semaphore_create(
|
||||
rtems_build_name('_', 'M', 'T', 'X'),
|
||||
1,
|
||||
attr,
|
||||
BSD_TASK_PRIORITY_RESOURCE_OWNER,
|
||||
&id
|
||||
);
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
m->lock_object.lo_id = id;
|
||||
|
||||
rtems_chain_append(&rtems_bsd_mtx_chain, &m->lock_object.lo_node);
|
||||
rtems_bsd_mutex_init(&m->lock_object, &m->mutex, class, name, type,
|
||||
flags);
|
||||
}
|
||||
|
||||
void
|
||||
_mtx_lock_flags(struct mtx *m, int opts, const char *file, int line)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
sc = rtems_semaphore_obtain(m->lock_object.lo_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
BSD_ASSERT_SC(sc);
|
||||
rtems_bsd_mutex_lock(&m->lock_object, &m->mutex);
|
||||
}
|
||||
|
||||
int
|
||||
_mtx_trylock(struct mtx *m, int opts, const char *file, int line)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
sc = rtems_semaphore_obtain(m->lock_object.lo_id, RTEMS_NO_WAIT, 0);
|
||||
if (sc == RTEMS_SUCCESSFUL) {
|
||||
return 1;
|
||||
} else if (sc == RTEMS_UNSATISFIED) {
|
||||
return 0;
|
||||
} else {
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return (rtems_bsd_mutex_trylock(&m->lock_object, &m->mutex));
|
||||
}
|
||||
|
||||
void
|
||||
_mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
sc = rtems_semaphore_release(m->lock_object.lo_id);
|
||||
BSD_ASSERT_SC(sc);
|
||||
rtems_bsd_mutex_unlock(&m->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -238,38 +195,12 @@ _mtx_assert(struct mtx *m, int what, const char *file, int line)
|
||||
|
||||
int mtx_owned(struct mtx *m)
|
||||
{
|
||||
Objects_Locations location;
|
||||
Semaphore_Control *sema = _Semaphore_Get(m->lock_object.lo_id, &location);
|
||||
|
||||
if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
|
||||
int owned = sema->Core_control.mutex.holder == _Thread_Executing;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return owned;
|
||||
} else {
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
BSD_PANIC("unexpected semaphore location or attributes");
|
||||
}
|
||||
return (rtems_bsd_mutex_owned(&m->mutex));
|
||||
}
|
||||
|
||||
int mtx_recursed(struct mtx *m)
|
||||
{
|
||||
Objects_Locations location;
|
||||
Semaphore_Control *sema = _Semaphore_Get(m->lock_object.lo_id, &location);
|
||||
|
||||
if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
|
||||
int recursed = sema->Core_control.mutex.nest_count != 0;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return recursed;
|
||||
} else {
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
BSD_PANIC("unexpected semaphore location or attributes");
|
||||
}
|
||||
return (rtems_bsd_mutex_recursed(&m->mutex));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -283,23 +214,8 @@ mtx_sysinit(void *arg)
|
||||
void
|
||||
mtx_destroy(struct mtx *m)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
do {
|
||||
sc = rtems_semaphore_delete(m->lock_object.lo_id);
|
||||
if (sc == RTEMS_RESOURCE_IN_USE) {
|
||||
BSD_ASSERT(mtx_owned(m));
|
||||
|
||||
mtx_unlock(m);
|
||||
} else {
|
||||
BSD_ASSERT_SC(sc);
|
||||
}
|
||||
} while (sc != RTEMS_SUCCESSFUL);
|
||||
|
||||
rtems_chain_extract(&m->lock_object.lo_node);
|
||||
|
||||
m->lock_object.lo_id = 0;
|
||||
m->lock_object.lo_flags &= ~LO_INITIALIZED;
|
||||
rtems_bsd_mutex_destroy(&m->lock_object, &m->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -46,17 +46,13 @@
|
||||
*/
|
||||
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
#include <machine/rtems-bsd-thread.h>
|
||||
#include <machine/rtems-bsd-support.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <machine/rtems-bsd-muteximpl.h>
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <rtems/bsd/sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <rtems/bsd/sys/lock.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#ifndef INVARIANTS
|
||||
#define _rw_assert(rw, what, file, line)
|
||||
@@ -83,8 +79,6 @@ struct lock_class lock_class_rw = {
|
||||
#endif
|
||||
};
|
||||
|
||||
RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_rwlock_chain);
|
||||
|
||||
void
|
||||
assert_rw(struct lock_object *lock, int what)
|
||||
{
|
||||
@@ -94,29 +88,15 @@ assert_rw(struct lock_object *lock, int what)
|
||||
void
|
||||
lock_rw(struct lock_object *lock, int how)
|
||||
{
|
||||
struct rwlock *rw;
|
||||
|
||||
rw = (struct rwlock *)lock;
|
||||
if (how)
|
||||
rw_wlock(rw);
|
||||
else
|
||||
rw_rlock(rw);
|
||||
rw_wlock((struct rwlock *)lock);
|
||||
}
|
||||
|
||||
int
|
||||
unlock_rw(struct lock_object *lock)
|
||||
{
|
||||
struct rwlock *rw;
|
||||
rw_unlock((struct rwlock *)lock);
|
||||
|
||||
rw = (struct rwlock *)lock;
|
||||
rw_assert(rw, RA_LOCKED | LA_NOTRECURSED);
|
||||
if (rw->rw_lock & RW_LOCK_READ) {
|
||||
rw_runlock(rw);
|
||||
return (0);
|
||||
} else {
|
||||
rw_wunlock(rw);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef KDTRACE_HOOKS
|
||||
@@ -136,34 +116,20 @@ void
|
||||
rw_init_flags(struct rwlock *rw, const char *name, int opts)
|
||||
{
|
||||
int flags;
|
||||
rtems_status_code sc;
|
||||
rtems_id id;
|
||||
rtems_attribute attr = RTEMS_LOCAL | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY;
|
||||
|
||||
flags = LO_UPGRADABLE;
|
||||
if (opts & RW_RECURSE)
|
||||
flags |= LO_RECURSABLE;
|
||||
|
||||
lock_init(&rw->lock_object, &lock_class_rw, name, NULL, flags);
|
||||
|
||||
sc = rtems_semaphore_create(
|
||||
rtems_build_name('_', '_', 'R', 'W'),
|
||||
1,
|
||||
attr,
|
||||
BSD_TASK_PRIORITY_RESOURCE_OWNER,
|
||||
&id
|
||||
);
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
rw->lock_object.lo_id = id;
|
||||
|
||||
rtems_chain_append(&rtems_bsd_rwlock_chain, &rw->lock_object.lo_node);
|
||||
rtems_bsd_mutex_init(&rw->lock_object, &rw->mutex, &lock_class_rw,
|
||||
name, NULL, flags);
|
||||
}
|
||||
|
||||
void
|
||||
rw_destroy(struct rwlock *rw)
|
||||
{
|
||||
mtx_destroy((struct mtx *) rw);
|
||||
|
||||
rtems_bsd_mutex_destroy(&rw->lock_object, &rw->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -185,55 +151,55 @@ rw_sysinit_flags(void *arg)
|
||||
int
|
||||
rw_wowned(struct rwlock *rw)
|
||||
{
|
||||
return mtx_owned((struct mtx *) rw);
|
||||
return (rtems_bsd_mutex_owned(&rw->mutex));
|
||||
}
|
||||
|
||||
void
|
||||
_rw_wlock(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
_mtx_lock_flags((struct mtx *) rw, 0, file, line);
|
||||
rtems_bsd_mutex_lock(&rw->lock_object, &rw->mutex);
|
||||
}
|
||||
|
||||
int
|
||||
_rw_try_wlock(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
return _mtx_trylock((struct mtx *) rw, 0, file, line);
|
||||
return (rtems_bsd_mutex_trylock(&rw->lock_object, &rw->mutex));
|
||||
}
|
||||
|
||||
void
|
||||
_rw_wunlock(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
_mtx_unlock_flags((struct mtx *) rw, 0, file, line);
|
||||
rtems_bsd_mutex_unlock(&rw->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
_rw_rlock(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
_mtx_lock_flags((struct mtx *) rw, 0, file, line);
|
||||
rtems_bsd_mutex_lock(&rw->lock_object, &rw->mutex);
|
||||
}
|
||||
|
||||
int
|
||||
_rw_try_rlock(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
return _mtx_trylock((struct mtx *) rw, 0, file, line);
|
||||
return (rtems_bsd_mutex_trylock(&rw->lock_object, &rw->mutex));
|
||||
}
|
||||
|
||||
void
|
||||
_rw_runlock(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
_mtx_unlock_flags((struct mtx *) rw, 0, file, line);
|
||||
rtems_bsd_mutex_unlock(&rw->mutex);
|
||||
}
|
||||
|
||||
int
|
||||
_rw_try_upgrade(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
return 1;
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
_rw_downgrade(struct rwlock *rw, const char *file, int line)
|
||||
{
|
||||
/* Nothing to do */
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
#ifdef INVARIANT_SUPPORT
|
||||
|
@@ -44,66 +44,11 @@
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <rtems/bsd/sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <rtems/bsd/sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <rtems/bsd/bsd.h>
|
||||
#include <rtems/shell.h>
|
||||
|
||||
static void
|
||||
rtems_bsd_dump_mtx(void)
|
||||
{
|
||||
rtems_chain_control *chain = &rtems_bsd_mtx_chain;
|
||||
rtems_chain_node *node = rtems_chain_first(chain);
|
||||
|
||||
printf("mtx dump:\n");
|
||||
|
||||
while (!rtems_chain_is_tail(chain, node)) {
|
||||
struct lock_object *lo = (struct lock_object *) node;
|
||||
|
||||
printf("\t%s: 0x%08x\n", lo->lo_name, lo->lo_id);
|
||||
|
||||
node = rtems_chain_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bsd_dump_sx(void)
|
||||
{
|
||||
rtems_chain_control *chain = &rtems_bsd_sx_chain;
|
||||
rtems_chain_node *node = rtems_chain_first(chain);
|
||||
|
||||
printf("sx dump:\n");
|
||||
|
||||
while (!rtems_chain_is_tail(chain, node)) {
|
||||
struct lock_object *lo = (struct lock_object *) node;
|
||||
|
||||
printf("\t%s: 0x%08x\n", lo->lo_name, lo->lo_id);
|
||||
|
||||
node = rtems_chain_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bsd_dump_condvar(void)
|
||||
{
|
||||
rtems_chain_control *chain = &rtems_bsd_condvar_chain;
|
||||
rtems_chain_node *node = rtems_chain_first(chain);
|
||||
|
||||
printf("condvar dump:\n");
|
||||
|
||||
while (!rtems_chain_is_tail(chain, node)) {
|
||||
struct cv *cv = (struct cv *) node;
|
||||
|
||||
printf("\t%s: 0x%08x\n", cv->cv_description, cv->cv_id);
|
||||
|
||||
node = rtems_chain_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_bsd_dump_thread(void)
|
||||
{
|
||||
@@ -122,7 +67,7 @@ rtems_bsd_dump_thread(void)
|
||||
}
|
||||
|
||||
static const char rtems_bsd_usage [] =
|
||||
"bsd {all|mtx|sx|condvar|thread|callout}";
|
||||
"bsd {all|condvar|thread|callout}";
|
||||
|
||||
#define CMP(s) all || strcasecmp(argv [1], s) == 0
|
||||
|
||||
@@ -138,18 +83,6 @@ rtems_bsd_info(int argc, char **argv)
|
||||
all = true;
|
||||
}
|
||||
|
||||
if (CMP("mtx")) {
|
||||
rtems_bsd_dump_mtx();
|
||||
usage = false;
|
||||
}
|
||||
if (CMP("sx")) {
|
||||
rtems_bsd_dump_sx();
|
||||
usage = false;
|
||||
}
|
||||
if (CMP("condvar")) {
|
||||
rtems_bsd_dump_condvar();
|
||||
usage = false;
|
||||
}
|
||||
if (CMP("thread")) {
|
||||
rtems_bsd_dump_thread();
|
||||
usage = false;
|
||||
|
@@ -38,11 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <machine/rtems-bsd-kernel-space.h>
|
||||
#include <machine/rtems-bsd-support.h>
|
||||
|
||||
#include <rtems/score/objectimpl.h>
|
||||
#include <rtems/rtems/attrimpl.h>
|
||||
#include <rtems/rtems/semimpl.h>
|
||||
#include <machine/rtems-bsd-muteximpl.h>
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <rtems/bsd/sys/types.h>
|
||||
@@ -75,8 +71,6 @@ struct lock_class lock_class_sx = {
|
||||
#endif
|
||||
};
|
||||
|
||||
RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_sx_chain);
|
||||
|
||||
void
|
||||
assert_sx(struct lock_object *lock, int what)
|
||||
{
|
||||
@@ -86,29 +80,15 @@ assert_sx(struct lock_object *lock, int what)
|
||||
void
|
||||
lock_sx(struct lock_object *lock, int how)
|
||||
{
|
||||
struct sx *sx;
|
||||
|
||||
sx = (struct sx *)lock;
|
||||
if (how)
|
||||
sx_xlock(sx);
|
||||
else
|
||||
sx_slock(sx);
|
||||
sx_xlock((struct sx *)lock);
|
||||
}
|
||||
|
||||
int
|
||||
unlock_sx(struct lock_object *lock)
|
||||
{
|
||||
struct sx *sx;
|
||||
sx_xunlock((struct sx *)lock);
|
||||
|
||||
sx = (struct sx *)lock;
|
||||
sx_assert(sx, SA_LOCKED | SA_NOTRECURSED);
|
||||
if (sx_xlocked(sx)) {
|
||||
sx_xunlock(sx);
|
||||
return (1);
|
||||
} else {
|
||||
sx_sunlock(sx);
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef KDTRACE_HOOKS
|
||||
@@ -136,89 +116,46 @@ void
|
||||
sx_init_flags(struct sx *sx, const char *description, int opts)
|
||||
{
|
||||
int flags;
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
rtems_id id = RTEMS_ID_NONE;
|
||||
rtems_attribute attr = RTEMS_LOCAL | RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE;
|
||||
|
||||
flags = LO_SLEEPABLE | LO_UPGRADABLE;
|
||||
if (opts & SX_RECURSE)
|
||||
flags |= LO_RECURSABLE;
|
||||
|
||||
lock_init(&sx->lock_object, &lock_class_sx, description, NULL, flags);
|
||||
|
||||
sc = rtems_semaphore_create(
|
||||
rtems_build_name( '_', 'S', 'X', ' '),
|
||||
1,
|
||||
attr,
|
||||
0,
|
||||
&id
|
||||
);
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
sx->lock_object.lo_id = id;
|
||||
|
||||
rtems_chain_append(&rtems_bsd_sx_chain, &sx->lock_object.lo_node);
|
||||
rtems_bsd_mutex_init(&sx->lock_object, &sx->mutex, &lock_class_sx,
|
||||
description, NULL, flags);
|
||||
}
|
||||
|
||||
void
|
||||
sx_destroy(struct sx *sx)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
sc = rtems_semaphore_delete( sx->lock_object.lo_id);
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
rtems_chain_extract(&sx->lock_object.lo_node);
|
||||
|
||||
sx->lock_object.lo_id = 0;
|
||||
sx->lock_object.lo_flags &= ~LO_INITIALIZED;
|
||||
rtems_bsd_mutex_destroy(&sx->lock_object, &sx->mutex);
|
||||
}
|
||||
|
||||
int
|
||||
_sx_xlock(struct sx *sx, int opts, const char *file, int line)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
rtems_bsd_mutex_lock(&sx->lock_object, &sx->mutex);
|
||||
|
||||
#warning "SX_INTERRUPTIBLE NOT SUPPORTED YET"
|
||||
/* BSD_ASSERT((opts & SX_INTERRUPTIBLE) == 0); */
|
||||
BSD_ASSERT(!rtems_interrupt_is_in_progress());
|
||||
|
||||
sc = rtems_semaphore_obtain( sx->lock_object.lo_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_sx_try_xlock(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
sc = rtems_semaphore_obtain( sx->lock_object.lo_id, RTEMS_NO_WAIT, 0);
|
||||
if (sc == RTEMS_SUCCESSFUL) {
|
||||
return 1;
|
||||
} else if (sc == RTEMS_UNSATISFIED) {
|
||||
return 0;
|
||||
} else {
|
||||
BSD_ASSERT_SC(sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return (rtems_bsd_mutex_trylock(&sx->lock_object, &sx->mutex));
|
||||
}
|
||||
|
||||
void
|
||||
_sx_xunlock(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
|
||||
sc = rtems_semaphore_release( sx->lock_object.lo_id);
|
||||
BSD_ASSERT_SC(sc);
|
||||
rtems_bsd_mutex_unlock(&sx->mutex);
|
||||
}
|
||||
|
||||
int
|
||||
_sx_try_upgrade(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
return 1;
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -322,18 +259,5 @@ _sx_assert(struct sx *sx, int what, const char *file, int line)
|
||||
int
|
||||
sx_xlocked(struct sx *sx)
|
||||
{
|
||||
Objects_Locations location;
|
||||
Semaphore_Control *sema = _Semaphore_Get(sx->lock_object.lo_id, &location);
|
||||
|
||||
if (location == OBJECTS_LOCAL && !_Attributes_Is_counting_semaphore(sema->attribute_set)) {
|
||||
int xlocked = sema->Core_control.mutex.holder == _Thread_Executing;
|
||||
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
return xlocked;
|
||||
} else {
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
BSD_PANIC("unexpected semaphore location or attributes");
|
||||
}
|
||||
return (rtems_bsd_mutex_owned(&sx->mutex));
|
||||
}
|
||||
|
Reference in New Issue
Block a user