import RT-Thread@9217865c without bsp, libcpu and components/net
This commit is contained in:
commit
e2376a3709
1414 changed files with 390370 additions and 0 deletions
130
components/vbus/watermark_queue.h
Normal file
130
components/vbus/watermark_queue.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* COPYRIGHT (C) 2011-2021, Real-Thread Information Technology Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2014-04-16 Grissiom first version
|
||||
*/
|
||||
|
||||
struct rt_watermark_queue
|
||||
{
|
||||
/* Current water level. */
|
||||
unsigned int level;
|
||||
unsigned int high_mark;
|
||||
unsigned int low_mark;
|
||||
rt_list_t suspended_threads;
|
||||
};
|
||||
|
||||
/** Init the struct rt_watermark_queue.
|
||||
*/
|
||||
void rt_wm_que_init(struct rt_watermark_queue *wg,
|
||||
unsigned int low, unsigned int high);
|
||||
void rt_wm_que_set_mark(struct rt_watermark_queue *wg,
|
||||
unsigned int low, unsigned int high);
|
||||
void rt_wm_que_dump(struct rt_watermark_queue *wg);
|
||||
|
||||
/* Water marks are often used in performance critical places. Benchmark shows
|
||||
* inlining functions will have 10% performance gain in some situation(for
|
||||
* example, VBus). So keep the inc/dec compact and inline. */
|
||||
|
||||
/** Increase the water level.
|
||||
*
|
||||
* It should be called in the thread that want to raise the water level. If the
|
||||
* current level is above the high mark, the thread will be suspended up to
|
||||
* @timeout ticks.
|
||||
*
|
||||
* @return RT_EOK if water level increased successfully. -RT_EFULL on @timeout
|
||||
* is zero and the level is above water mark. -RT_ETIMEOUT if timeout occurred.
|
||||
*/
|
||||
rt_inline rt_err_t rt_wm_que_inc(struct rt_watermark_queue *wg,
|
||||
int timeout)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
/* Assert as early as possible. */
|
||||
if (timeout != 0)
|
||||
{
|
||||
RT_DEBUG_IN_THREAD_CONTEXT;
|
||||
}
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
while (wg->level > wg->high_mark)
|
||||
{
|
||||
rt_thread_t thread;
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
rt_hw_interrupt_enable(level);
|
||||
return -RT_EFULL;
|
||||
}
|
||||
|
||||
thread = rt_thread_self();
|
||||
thread->error = RT_EOK;
|
||||
rt_thread_suspend(thread);
|
||||
rt_list_insert_after(&wg->suspended_threads, &thread->tlist);
|
||||
if (timeout > 0)
|
||||
{
|
||||
rt_timer_control(&(thread->thread_timer),
|
||||
RT_TIMER_CTRL_SET_TIME,
|
||||
&timeout);
|
||||
rt_timer_start(&(thread->thread_timer));
|
||||
}
|
||||
rt_hw_interrupt_enable(level);
|
||||
rt_schedule();
|
||||
if (thread->error != RT_EOK)
|
||||
return thread->error;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
}
|
||||
|
||||
wg->level++;
|
||||
|
||||
if (wg->level == 0)
|
||||
{
|
||||
wg->level = ~0;
|
||||
}
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/** Decrease the water level.
|
||||
*
|
||||
* It should be called by the consumer that drain the water out. If the water
|
||||
* level reached low mark, all the thread suspended in this queue will be waken
|
||||
* up. It's safe to call this function in interrupt context.
|
||||
*/
|
||||
rt_inline void rt_wm_que_dec(struct rt_watermark_queue *wg)
|
||||
{
|
||||
int need_sched = 0;
|
||||
rt_base_t level;
|
||||
|
||||
if (wg->level == 0)
|
||||
return;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
wg->level--;
|
||||
if (wg->level == wg->low_mark)
|
||||
{
|
||||
/* There should be spaces between the low mark and high mark, so it's
|
||||
* safe to resume all the threads. */
|
||||
while (!rt_list_isempty(&wg->suspended_threads))
|
||||
{
|
||||
rt_thread_t thread;
|
||||
|
||||
thread = rt_list_entry(wg->suspended_threads.next,
|
||||
struct rt_thread,
|
||||
tlist);
|
||||
rt_thread_resume(thread);
|
||||
need_sched = 1;
|
||||
}
|
||||
}
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
if (need_sched)
|
||||
rt_schedule();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue