/*
sem.h - Semaphore Function Class
Copyright (c) 2021 Sasapea's Lab. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#include <stdint.h>
#include <stdbool.h>
#include <util/atomic.h>
#include "avros.h"
Sem::Sem(uint8_t init, uint8_t limit)
: _count(init)
{
_limit = _BV(sizeof(_count) << 3) - 1;
if (limit && (limit < _limit))
_limit = limit;
}
Sem::~Sem(void)
{
}
uint8_t Sem::acquire(int32_t timeout)
{
uint8_t rv = WAIT_TIMEOUT;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
if (_count)
{
--_count;
rv = WAIT_OBJECT;
}
else if (timeout)
{
rv = Wait::sleep(timeout);
}
}
return rv;
}
bool Sem::release(void)
{
bool rv = true;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
if (!Wait::wakeup())
{
if (_count < _limit)
++_count;
else
rv = false;
}
}
return rv;
}