From 0e8fb6498892263837b1bc0a778da31e8e4ea587 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Thu, 6 Apr 2017 11:27:06 +0900 Subject: [PATCH] kernel/semaphore: fix compilation errors Handle a case of missing proxy sem_setprotocol. Reorder so that (1) this error is avoided, and (2) no proxy is needed if priority inheritance is not enabled. Change-Id: I4421e3e929567fcdb43fdd2e031e49ceb6fc252f Signed-off-by: Gregory Nutt [Shin: backported 73fc186b from NuttX] Signed-off-by: Heesub Shin --- lib/libc/semaphore/Make.defs | 4 ++ lib/libc/semaphore/sem_setprotocol.c | 130 ++++++++++++++++++++++++++++++++++ os/kernel/semaphore/Make.defs | 4 +- os/kernel/semaphore/sem_setprotocol.c | 8 +-- os/syscall/syscall.csv | 2 +- 5 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 lib/libc/semaphore/sem_setprotocol.c diff --git a/lib/libc/semaphore/Make.defs b/lib/libc/semaphore/Make.defs index 56300e7..282a34b 100644 --- a/lib/libc/semaphore/Make.defs +++ b/lib/libc/semaphore/Make.defs @@ -54,6 +54,10 @@ CSRCS += sem_init.c sem_getprotocol.c sem_getvalue.c +ifneq ($(CONFIG_PRIORITY_INHERITANCE),y) +CSRCS += sem_setprotocol.c +endif + # Add the semaphore directory to the build DEPPATH += --dep-path semaphore diff --git a/lib/libc/semaphore/sem_setprotocol.c b/lib/libc/semaphore/sem_setprotocol.c new file mode 100644 index 0000000..64a74a9 --- /dev/null +++ b/lib/libc/semaphore/sem_setprotocol.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ +/**************************************************************************** + * lib/libc/semaphore/sem_setprotocol.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#ifndef CONFIG_PRIORITY_INHERITANCE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sem_setprotocol + * + * Description: + * Set semaphore protocol attribute. + * + * One particularly important use of this furnction is when a semaphore + * is used for inter-task communication like: + * + * TASK A TASK B + * sem_init(sem, 0, 0); + * sem_wait(sem); + * sem_post(sem); + * Awakens as holder + * + * In this case priority inheritance can interfere with the operation of + * the semaphore. The problem is that when TASK A is restarted it is a + * holder of the semaphore. However, it never calls sem_post(sem) so it + * becomes *permanently* a holder of the semaphore and may have its + * priority boosted when any other task tries to acquire the semaphore. + * + * The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after + * the sem_init() call so that there will be no priority inheritance + * operations on this semaphore. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +int sem_setprotocol(FAR sem_t *sem, int protocol) +{ + int errcode; + + DEBUGASSERT(sem != NULL); + + switch (protocol) { + case SEM_PRIO_NONE: + return OK; + + case SEM_PRIO_INHERIT: + case SEM_PRIO_PROTECT: + errcode = ENOSYS; + break; + + default: + errcode = EINVAL; + break; + } + + set_errno(errcode); + return ERROR; +} + +#endif /* !CONFIG_PRIORITY_INHERITANCE */ diff --git a/os/kernel/semaphore/Make.defs b/os/kernel/semaphore/Make.defs index 4b90458..5f0b1aa 100644 --- a/os/kernel/semaphore/Make.defs +++ b/os/kernel/semaphore/Make.defs @@ -53,10 +53,10 @@ # Add semaphore-related files to the build CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_timedwait.c -CSRCS += sem_post.c sem_recover.c sem_reset.c sem_setprotocol.c sem_waitirq.c +CSRCS += sem_post.c sem_recover.c sem_reset.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += sem_initialize.c sem_holder.c +CSRCS += sem_initialize.c sem_holder.c sem_setprotocol.c endif # Include semaphore build support diff --git a/os/kernel/semaphore/sem_setprotocol.c b/os/kernel/semaphore/sem_setprotocol.c index e3eded7..85ba240 100644 --- a/os/kernel/semaphore/sem_setprotocol.c +++ b/os/kernel/semaphore/sem_setprotocol.c @@ -63,6 +63,8 @@ #include "semaphore/semaphore.h" +#ifdef CONFIG_PRIORITY_INHERITANCE + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -111,7 +113,6 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) switch (protocol) { case SEM_PRIO_NONE: -#ifdef CONFIG_PRIORITY_INHERITANCE /* Disable priority inheritance */ sem->flags |= PRIOINHERIT_FLAGS_DISABLE; @@ -119,16 +120,13 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) /* Remove any current holders */ sem_destroyholder(sem); -#endif return OK; case SEM_PRIO_INHERIT: -#ifdef CONFIG_PRIORITY_INHERITANCE /* Enable priority inheritance (dangerous) */ sem->flags &= ~PRIOINHERIT_FLAGS_DISABLE; return OK; -#endif case SEM_PRIO_PROTECT: /* Not yet supported */ @@ -144,3 +142,5 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) set_errno(errcode); return ERROR; } + +#endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/os/syscall/syscall.csv b/os/syscall/syscall.csv index 2bd106a..ed2677d 100644 --- a/os/syscall/syscall.csv +++ b/os/syscall/syscall.csv @@ -113,7 +113,7 @@ "sem_destroy", "semaphore.h", "", "int", "FAR sem_t*" "sem_open", "semaphore.h", "defined(CONFIG_FS_NAMED_SEMAPHORES)", "FAR sem_t*", "FAR const char*", "int", "..." "sem_post", "semaphore.h", "", "int", "FAR sem_t*" -"sem_setprotocol","tinyara/semaphore.h","","int","FAR sem_t*","int" +"sem_setprotocol","tinyara/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_timedwait", "semaphore.h", "", "int", "FAR sem_t*", "FAR const struct timespec *" "sem_trywait", "semaphore.h", "", "int", "FAR sem_t*" "sem_unlink", "semaphore.h", "defined(CONFIG_FS_NAMED_SEMAPHORES)", "int", "FAR const char*" -- 2.7.4