diff options
| author | geniusgogo <[email protected]> | 2023-12-21 10:31:27 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-12-21 10:31:27 +0800 |
| commit | 3dfafcd1d982c09b1718f36c956263fd1ef507db (patch) | |
| tree | 276b33e3376cc061f13190bac1d5de6a178df88a /src | |
| parent | 0541b39d61d4db7577037d51be70eb09d0a609e2 (diff) | |
add semaphore max value control. (#8390)
Diffstat (limited to 'src')
| -rw-r--r-- | src/ipc.c | 71 |
1 files changed, 52 insertions, 19 deletions
@@ -271,6 +271,23 @@ rt_inline rt_err_t _ipc_list_resume_all(rt_list_t *list) * @{ */ +static void _sem_object_init(rt_sem_t sem, + rt_uint16_t value, + rt_uint8_t flag, + rt_uint16_t max_value) +{ + /* initialize ipc object */ + _ipc_object_init(&(sem->parent)); + + sem->max_value = max_value; + /* set initial value */ + sem->value = value; + + /* set parent */ + sem->parent.parent.flag = flag; + rt_spin_lock_init(&(sem->spinlock)); +} + /** * @brief This function will initialize a static semaphore object. * @@ -321,15 +338,7 @@ rt_err_t rt_sem_init(rt_sem_t sem, /* initialize object */ rt_object_init(&(sem->parent.parent), RT_Object_Class_Semaphore, name); - /* initialize ipc object */ - _ipc_object_init(&(sem->parent)); - - /* set initial value */ - sem->value = (rt_uint16_t)value; - - /* set parent */ - sem->parent.parent.flag = flag; - rt_spin_lock_init(&(sem->spinlock)); + _sem_object_init(sem, value, flag, RT_SEM_VALUE_MAX); return RT_EOK; } @@ -422,15 +431,7 @@ rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag) if (sem == RT_NULL) return sem; - /* initialize ipc object */ - _ipc_object_init(&(sem->parent)); - - /* set initial value */ - sem->value = value; - - /* set parent */ - sem->parent.parent.flag = flag; - rt_spin_lock_init(&(sem->spinlock)); + _sem_object_init(sem, value, flag, RT_SEM_VALUE_MAX); return sem; } @@ -670,7 +671,7 @@ rt_err_t rt_sem_release(rt_sem_t sem) } else { - if(sem->value < RT_SEM_VALUE_MAX) + if(sem->value < sem->max_value) { sem->value ++; /* increase value */ } @@ -732,6 +733,38 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) return RT_EOK; } + else if (cmd == RT_IPC_CMD_SET_VLIMIT) + { + rt_ubase_t max_value; + rt_bool_t need_schedule = RT_FALSE; + + max_value = (rt_uint16_t)((rt_ubase_t)arg); + if (max_value > RT_SEM_VALUE_MAX || max_value < 1) + { + return -RT_EINVAL; + } + + level = rt_spin_lock_irqsave(&(sem->spinlock)); + if (max_value < sem->value) + { + if (!rt_list_isempty(&sem->parent.suspend_thread)) + { + /* resume all waiting thread */ + _ipc_list_resume_all(&sem->parent.suspend_thread); + need_schedule = RT_TRUE; + } + } + /* set new value */ + sem->max_value = max_value; + rt_spin_unlock_irqrestore(&(sem->spinlock), level); + + if (need_schedule) + { + rt_schedule(); + } + + return RT_EOK; + } return -RT_ERROR; } |
