Kernel semaphore

The EVL core provides a counting semaphore API in kernel space, which drivers can use to synchronize threads, with a requirement for waiters to be EVL threads running on the out-of-band stage. However, a semaphore may be posted by any kind of thread (EVL or regular), running on any stage at the time of the call.

Semaphore services

void evl_init_ksem(struct evl_ksem *ksem, unsigned int value)

This call initializes a kernel semaphore.

  • ksem

    A semaphore descriptor is constructed by evl_init_ksem(), which contains ancillary information other calls will need. ksem is a pointer to such descriptor of type struct evl_ksem.

  • value

    The initial value of the semaphore.


  • void evl_destroy_ksem(struct evl_ksem *ksem)

    This call destroys an existing EVL kernel semaphore. Any thread which might be waiting on the semaphore is woken up by this call, receiving a ‘resource removed’ status (-EIDRM).

  • ksem

    The descriptor of the kernel semaphore to be destroyed.


  • int evl_down(struct evl_ksem *ksem)

    This service decrements the semaphore by one. If the resulting semaphore value is negative, the caller is blocked until a call to evl_up() eventually releases it. Otherwise, the caller returns immediately. Waiters are queued by order of scheduling priority.

  • ksem

    The semaphore descriptor constructed by either evl_init_ksem(), or statically built with EVL_KSEM_INITIALIZER.


  • int evl_down_timeout(struct evl_ksem *ksem, ktime_t timeout)

    This call is a variant of evl_down() which allows specifying a timeout on the down operation, so that the caller is automatically unblocked when a time limit is reached.

  • ksem

    The semaphore descriptor constructed by either evl_init_ksem(), or statically built with EVL_KSEM_INITIALIZER.

  • timeout

    A time limit for the call, which is implicitly based on the monotonic clock.

  • Zero is returned on success, otherwise:

    • -ETIMEDOUT The timeout fired, after the amount of time specified by timeout.

    • -EIDRM The semaphore was deleted while the caller was sleeping on it. When this status is returned, the semaphore must be considered stale and should not be accessed anymore.


    int evl_trydown(struct evl_ksem *ksem)

    This call attempts to decrement the semaphore provided the result does not yields a negative count. Otherwise, the routine immediately returns with an error status.

    Zero is returned on success, otherwise:

    -EAGAIN the semaphore value is zero or negative at the time of the call.


    void evl_up(struct evl_ksem *ksem)

    This call posts a semaphore by incrementing its count by one. If a thread is sleeping on the semaphore as a result of a previous call to evl_down() or evl_down_timeout(), the thread heading the wait queue is unblocked.

  • ksem

    The semaphore descriptor constructed by either evl_init_ksem(), or statically built with EVL_KSEM_INITIALIZER.


  • void evl_broadcast(struct evl_ksem *ksem)

    This call unblocks all the threads blocked on the semaphore at the time of the call. Every unblocked thread receives a success status.

  • ksem

    The semaphore descriptor constructed by either evl_init_ksem(), or statically built with EVL_KSEM_INITIALIZER.


  • EVL_KSEM_INITIALIZER(name)

    A macro which expands as a static initializer you can use in a C statement creating an EVL kernel semaphore.

  • name

    The C variable name to which the initializer should be assigned.

  • struct evl_ksem foo = EVL_KSEM_INITIALIZER(foo);
    

    DEFINE_EVL_KSEM(name)

    A macro which expands as a C statement defining an initialized EVL kernel semaphore.

  • name

    The C variable name of the kernel semaphore to define.

  • /*
     * The following expands as:
     * static struct evl_ksem bar = EVL_KSEM_INITIALIZER(bar);
     */
    static DEFINE_EVL_KSEM(bar);
    

    Last modified: Sun, 21 May 2023 18:02:07 +0200