sys_arch_protect() and sys_arch_unprotect() is always called in pairs with
call order maintained. From rtos prospective, you can consider
sys_arch_protect() as enter_critical_section() and sys_arch_unprotect() as
exit_critical_section(). These calls might already be provided by rtos
you're using.

And right order has to be maintained for protect/unprotect calls e.g.

lev1 = sys_arch_protect()
lev2 = sys_arch_protect()
lev3 = sys_arch_protect()
sys_arch_unprotect(lev3)
sys_arch_unprotect(lev2)
sys_arch_unprotect(lev1)

Rest depends on how you actually implement these calls.

Regards,
Ajay Bhargav

On Sun, Nov 14, 2021, 11:06 PM Grant Edwards <grant.b.edwa...@gmail.com>
wrote:

> A couple questions about sys_arch_protect/unprotect
>
>  1. Are protect/unprotect calls required to nest?
>
>  2. Does the level passed to unprotect() have to do something?
>
>
> I think I've found another instance where the original authors of my
> sys_arch.c implemented something that meets the requirements stated in
> the documentation, but failed to satisfy an unstated requirement.
>
> I also can't figure out how the freeRTOS port satisfies one of the
> stated requirements.
>
> According to https://www.nongnu.org/lwip/2_1_x/group__sys__prot.html
>
>     SYS_ARCH_PROTECT Perform a "fast" protect. This could be
>     implemented by disabling interrupts for an embedded system or by
>     using a semaphore or mutex. The implementation should allow
>     calling SYS_ARCH_PROTECT when already protected. The old
>     protection level is returned in the variable "lev".
>
>
> Nesting
> =======
>
> The implemenatation I'm looking at supports both those requirements:
>
>  1. Calling sys_arch_protect() while already protected is allowed.
>
>  2. sys_arch_protect() returns the old protection level.
>
> The protection level is 0 or 1.
>
> sys_arch_protect() disables the scheduler, sets level to 1, returns old
> level.
>
> sys_arch_unprotect() enables the scheduler, sets level to 0. It
> ignores the parameter value, as other ports seem to do.
>
> Looking at the lwIP source code and the freeRTOS port leads me to
> believe that there is an unstated requirement that protect/unprotect
> calls should nest (should behave like a recursive/rentrant mutex as
> described at https://en.wikipedia.org/wiki/Reentrant_mutex).
>
> IOW: 3 successive calls to protect() would require 3 successive calls
> to unprotect() before the scheduler is re-enabled.
>
> Simply allowing sys_arch_protect() to be called while already
> protected is not sufficient.
>
> Is that correct?
>
>
> sys_arch_unprotect() parameter value
> ====================================
>
> I can't figure out how the freeRTOS port satisfies the requirement that
>
>     SYS_ARCH_UNPROTECT Perform a "fast" set of the protection level to
>     "lev".
>
> AFAICT, the value of "lev" does not affect the behavior at all. The
> requirement would seem to be that the value of "lev" can be used to
> override the nesting behavior that one would expect from a standard
> recursive mutex:
>
>   // context switching allowed here
>
>   sys_prot_t lev;
>   lev = sys_arch_prot();
>   // context switching disabled here
>   sys_arch_protect();
>   sys_arch_protect();
>   sys_arch_protect();
>   sys_arch_protect();
>   sys_arch_unprotect(lev);
>
>   // context switching allowed here
>
>
> I don't see how freeRTOS meets that requirement.
>
> Do I need to implement that requirement?
>
> --
> Grant
>
>
> _______________________________________________
> lwip-users mailing list
> lwip-users@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/lwip-users
>
_______________________________________________
lwip-users mailing list
lwip-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to