77 * Date Author Notes
88 * 2019-10-12 Jesven first version
99 * 2023-02-20 wangxiaoyao adapt to mm
10+ * 2025-11-06 ibvqeibob add Doxygen comments for lwp shared memory APIs
1011 */
1112#include <rthw.h>
1213#include <rtthread.h>
1920#include <lwp_user_mm.h>
2021#include <mmu.h>
2122
22- /* the kernel structure to represent a share-memory */
23+ /**
24+ * @brief Kernel control block for a shared memory segment.
25+ *
26+ * Each lwp_shm_struct represents one shared memory region. It records
27+ * the physical address, size, reference count and key. The embedded
28+ * mem_obj is used together with the aspace/varea mechanism to handle
29+ * mapping and page faults for this segment.
30+ */
2331struct lwp_shm_struct
2432{
25- struct rt_mem_obj mem_obj ;
26- size_t addr ; /* point to the next item in the free list when not used */
27- size_t size ;
28- int ref ;
29- size_t key ;
33+ struct rt_mem_obj mem_obj ; /**< Memory object interface used by aspace/varea */
34+ size_t addr ; /**< Physical address of the shared memory; used as next pointer in the free list when unused */
35+ size_t size ; /**< Size of the shared memory in bytes, page aligned */
36+ int ref ; /**< Reference count of mappings to this shared memory */
37+ size_t key ; /**< User-visible key used to look up the shared memory */
3038};
3139
3240static struct lwp_avl_struct * shm_tree_key ;
@@ -189,7 +197,22 @@ static int _lwp_shmget(size_t key, size_t size, int create)
189197 return -1 ;
190198}
191199
192- /* A wrapping function, get the shared memory with interrupts disabled. */
200+ /**
201+ * @brief Get or create a shared memory segment by key.
202+ *
203+ * Under the memory management lock, this function looks up an existing
204+ * shared memory control block by key. If it does not exist and @p create
205+ * is non-zero, a new segment is created with the requested size, physical
206+ * pages are allocated and the segment is inserted into the internal index
207+ * trees.
208+ *
209+ * @param[in] key Key used to identify the shared memory segment.
210+ * @param[in] size Requested size in bytes; only effective when creating.
211+ * @param[in] create Non-zero to allow creation; zero to only search.
212+ *
213+ * @return On success, returns a non-negative shared memory id.
214+ * On failure, returns -1.
215+ */
193216int lwp_shmget (size_t key , size_t size , int create )
194217{
195218 int ret = 0 ;
@@ -253,7 +276,19 @@ static int _lwp_shmrm(int id)
253276 return 0 ;
254277}
255278
256- /* A wrapping function, free the shared memory with interrupt disabled. */
279+ /**
280+ * @brief Remove a shared memory segment by id.
281+ *
282+ * The internal control block is located by @p id. If the reference count
283+ * is zero, the physical pages, control block and AVL index nodes are freed.
284+ * If the segment is still referenced, no memory is actually released.
285+ *
286+ * @param[in] id Shared memory id returned by lwp_shmget().
287+ *
288+ * @return Returns 0 on success. If @p id is invalid or internal checks
289+ * fail, -1 is returned. When the reference count is non-zero,
290+ * 0 is returned but the segment is not freed.
291+ */
257292int lwp_shmrm (int id )
258293{
259294 int ret = 0 ;
@@ -300,7 +335,21 @@ static void *_lwp_shmat(int id, void *shm_vaddr)
300335 return va ;
301336}
302337
303- /* A wrapping function: attach the shared memory to the specified address. */
338+ /**
339+ * @brief Map a shared memory segment into the current LWP.
340+ *
341+ * The shared memory control block is located by @p id and mapped into the
342+ * user address space of the current LWP. If @p shm_vaddr is not RT_NULL,
343+ * the system tries to map the segment at the specified virtual address,
344+ * which must be page aligned.
345+ *
346+ * @param[in] id Shared memory id returned by lwp_shmget().
347+ * @param[in] shm_vaddr Desired user virtual address; if RT_NULL, the
348+ * system chooses an address. When not RT_NULL it
349+ * must be page aligned.
350+ *
351+ * @return The mapped user virtual address on success, or RT_NULL on failure.
352+ */
304353void * lwp_shmat (int id , void * shm_vaddr )
305354{
306355 void * ret = RT_NULL ;
@@ -346,6 +395,19 @@ static int _lwp_shm_ref_inc(struct rt_lwp *lwp, void *shm_vaddr)
346395 return -1 ;
347396}
348397
398+ /**
399+ * @brief Increase the reference count of a shared memory segment.
400+ *
401+ * The shared memory control block is located according to the given
402+ * @p lwp and the user virtual address @p shm_vaddr. If found, its
403+ * reference count is increased by one.
404+ *
405+ * @param[in] lwp LWP object to operate on.
406+ * @param[in] shm_vaddr User virtual address where the shared memory
407+ * is mapped in this LWP.
408+ *
409+ * @return The new reference count on success, or -1 on failure.
410+ */
349411int lwp_shm_ref_inc (struct rt_lwp * lwp , void * shm_vaddr )
350412{
351413 int ret = 0 ;
@@ -369,6 +431,19 @@ static int _lwp_shm_ref_dec(struct rt_lwp *lwp, void *shm_vaddr)
369431 return -1 ;
370432}
371433
434+ /**
435+ * @brief Decrease the reference count of a shared memory segment.
436+ *
437+ * The shared memory control block is located according to the given
438+ * @p lwp and the user virtual address @p shm_vaddr. If it exists and
439+ * the reference count is greater than zero, the count is decreased by one.
440+ *
441+ * @param[in] lwp LWP object to operate on.
442+ * @param[in] shm_vaddr User virtual address where the shared memory
443+ * is mapped in this LWP.
444+ *
445+ * @return The new reference count on success, or -1 on failure.
446+ */
372447int lwp_shm_ref_dec (struct rt_lwp * lwp , void * shm_vaddr )
373448{
374449 int ret = 0 ;
@@ -400,7 +475,16 @@ int _lwp_shmdt(void *shm_vaddr)
400475 return ret ;
401476}
402477
403- /* A wrapping function: detach the mapped shared memory. */
478+ /**
479+ * @brief Unmap a shared memory segment from the current LWP.
480+ *
481+ * The mapping at @p shm_vaddr in the current LWP address space is
482+ * removed. Internal errors are translated into a generic error code.
483+ *
484+ * @param[in] shm_vaddr User virtual address of the shared memory mapping.
485+ *
486+ * @return Returns 0 on success, or -1 on failure.
487+ */
404488int lwp_shmdt (void * shm_vaddr )
405489{
406490 int ret = 0 ;
@@ -429,7 +513,17 @@ void *_lwp_shminfo(int id)
429513 return (void * )((char * )p -> addr - PV_OFFSET ); /* get the virtual address */
430514}
431515
432- /* A wrapping function: get the virtual address of a shared memory. */
516+ /**
517+ * @brief Get the kernel virtual address of a shared memory segment.
518+ *
519+ * The internal control block is located by @p id and the kernel
520+ * virtual address corresponding to that shared memory is returned.
521+ *
522+ * @param[in] id Shared memory id returned by lwp_shmget().
523+ *
524+ * @return Kernel virtual address of the shared memory on success,
525+ * or RT_NULL on failure.
526+ */
433527void * lwp_shminfo (int id )
434528{
435529 void * vaddr = RT_NULL ;
@@ -451,6 +545,13 @@ static int _shm_info(struct lwp_avl_struct* node_key, void *data)
451545 return 0 ;
452546}
453547
548+ /**
549+ * @brief Print information of all shared memory segments.
550+ *
551+ * This function prints the key, physical address, size and id of each
552+ * shared memory segment to the console. It is exported as the Finsh/Msh
553+ * command @c list_shm for debugging and inspection.
554+ */
454555void list_shm (void )
455556{
456557 rt_kprintf (" key paddr size id\n" );
0 commit comments