/* * remote_busylock.h: remote kernel busy-waiting lock definition. * * Authors Alain Greiner (2016,2017,2018) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-kernel; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _REMOTE_BUSYLOCK_H_ #define _REMOTE_BUSYLOCK_H_ #include #include #include #include /******************************************************************************************* * This synchronisation object sequencializes all concurrent read or write accesses to a * shared object located in any cluster, made by any thread(s) running in any cluster. * It uses a busy waiting policy when the lock is taken by another thread, and should * be used ro execute very short actions, such as basic allocators, or to protect * higher level synchronisation objects, such as remote_queuelock and remote_rwlock. * * WARNING: a thread cannot yield when it is owning a busylock (local or remote). * * - To acquire the lock, we use a ticket policy to avoid starvation: the calling thread * makes an atomic increment on a "ticket" allocator, and keep polling the "current" * value until current == ticket. * * - To release the lock, the owner thread increments the "current" value, * decrements its busylocks counter. * * - When a thread takes a busylock, it enters a critical section: the busylock_acquire() * function disables the IRQs, takes the lock, increments the thread busylocks counter, * save the SR in the lock descriptor and returns. * * - The busylock_release() function decrements the thread busylock counter, * restores the SR to exit the critical section, and returns * * - If a thread owning a busylock (local or remote) tries to deschedule, the scheduler * signals a kernel panic. ******************************************************************************************/ /******************************************************************************************* * This structure defines a remote_busylock. * - The and fields implement the ticket policy described above. * - The and fields are used for debug. The type defines the lock usage, * as detailed in the kernel_config.h file. * - The field is used to implement the critical section as decribed above. ******************************************************************************************/ typedef struct remote_busylock_s { uint32_t ticket; /*! next free ticket index */ volatile uint32_t current; /*! current owner index */ uint32_t type; /*! lock type for debug */ reg_t save_sr; /*! SR value */ #if DEBUG_BUSYLOCK xlist_entry_t xlist; /*! member of list of locks taken by same thread */ #endif } remote_busylock_t; /******************************************************************************************* * This function initializes a remote busylock. ******************************************************************************************* * @ lock_xp : extended pointer on remote busylock. * @ type : lock type for debug. ******************************************************************************************/ void remote_busylock_init( xptr_t lock_xp, uint32_t type ); /******************************************************************************************* * This blocking function uses a busy waiting strategy to acquire a remote_busylock. * It makes an atomic increment on the "ticket" field to get a ticket value and increment * the ticket allocator. * Then it polls the "current" field until (current == ticket), and returns. ******************************************************************************************* * @ lock_xp : extended pointer on remote busylock ******************************************************************************************/ void remote_busylock_acquire( xptr_t lock_xp ); /******************************************************************************************* * This function releases a busylock by incrementing the "current field". ******************************************************************************************* * @ lock_xp : extended pointer on remote busylock ******************************************************************************************/ void remote_busylock_release( xptr_t lock_xp ); #endif /* _REMOTE_BUSYLOCK_H_ */