/**************************************************************************** * sched/semaphore/sem_setprotocol.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you 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. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include "semaphore/semaphore.h" #ifdef CONFIG_PRIORITY_INHERITANCE /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: nxsem_set_protocol * * Description: * Set semaphore protocol attribute. * * One particularly important use of this function is when a semaphore * is used for inter-task communication like: * * TASK A TASK B * nxsem_init(sem, 0, 0); * nxsem_wait(sem); * nxsem_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 nxsem_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 nxsem_set_protocol(SEM_PRIO_NONE) immediately after * the sem_init() call so that there will be no priority inheritance * operations on this semaphore. * * Input Parameters: * sem - A pointer to the semaphore whose attributes are to be * modified * protocol - The new protocol to use * * Returned Value: * This is an internal OS interface and should not be used by applications. * It follows the NuttX internal error return policy: Zero (OK) is * returned on success. A negated errno value is returned on failure. * ****************************************************************************/ int nxsem_set_protocol(FAR sem_t *sem, int protocol) { DEBUGASSERT(sem != NULL); switch (protocol) { case SEM_PRIO_NONE: /* Disable priority inheritance */ sem->flags &= ~PRIOINHERIT_FLAGS_ENABLE; /* Remove any current holders */ nxsem_destroyholder(sem); return OK; case SEM_PRIO_INHERIT: /* Enable priority inheritance (dangerous) */ sem->flags |= PRIOINHERIT_FLAGS_ENABLE; return OK; case SEM_PRIO_PROTECT: /* Not yet supported */ return -ENOTSUP; default: break; } return -EINVAL; } /**************************************************************************** * Name: sem_setprotocol * * Description: * Set semaphore protocol attribute. * * One particularly important use of this function is when a semaphore * is used for inter-task communication like: * * TASK A TASK B * sem_init(sem, 0, 0); * nxsem_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. * * Input Parameters: * sem - A pointer to the semaphore whose attributes are to be * modified * protocol - The new protocol to use * * Returned Value: * This function is exposed as a non-standard application interface. It * returns zero (OK) if successful. Otherwise, -1 (ERROR) is returned and * the errno value is set appropriately. * ****************************************************************************/ int sem_setprotocol(FAR sem_t *sem, int protocol) { int ret; ret = nxsem_set_protocol(sem, protocol); if (ret < 0) { set_errno(-ret); ret = ERROR; } return ret; } #endif /* CONFIG_PRIORITY_INHERITANCE */