source: trunk/kernel/libk/remote_busylock.h @ 636

Last change on this file since 636 was 624, checked in by alain, 6 years ago

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

File size: 5.5 KB
Line 
1/*
2 * remote_busylock.h: remote kernel busy-waiting lock definition.     
3 *
4 * Authors  Alain Greiner (2016,2017,2018,2019)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#ifndef _REMOTE_BUSYLOCK_H_
25#define _REMOTE_BUSYLOCK_H_
26
27#include <kernel_config.h>
28#include <hal_kernel_types.h>
29#include <hal_shared_types.h>
30#include <xlist.h>
31
32/*******************************************************************************************
33 * This synchronisation object sequencializes all concurrent read or write accesses to a
34 * shared object located in any cluster, made by any thread(s) running in any cluster.
35 * It uses a busy waiting policy when the lock is taken by another thread, and should
36 * be used ro execute very short actions, such as basic allocators, or to protect 
37 * higher level synchronisation objects, such as remote_queuelock and remote_rwlock.
38 *
39 * - To acquire the lock, we use a ticket policy to avoid starvation: the calling thread
40 *   makes an atomic increment on a "ticket" allocator, and keep polling the "current"
41 *   value  until current == ticket.
42 *
43 * - To release the lock, the owner thread increments the "current" value.
44 *
45 * - When a thread takes a busylock, it enters a critical section: the acquire()
46 *   function disables the IRQs, takes the lock, increments the thread busylocks counter,
47 *   save the SR in the lock descriptor and returns.
48 *
49 * - The release() function releases the lock, decrements the thread busylock
50 *   counter, restores the SR to exit the critical section, and returns.
51 *
52 * WARNING: a thread cannot yield when it is holding a busylock (local or remote).
53 *
54 * This rule is checked by all functions containing a thread_yield() AND by the scheduler,
55 * thanks to the busylocks counter stored in the calling thread descriptor.
56 * 1) all functions call "thread_assert_can_yield()" before calling "thread_yield()".
57 * 2) The scheduler checks that the calling thread does not hold any busylock.
58 * In case of violation the core goes to sleep after a [PANIC] message on TXT0.
59 ******************************************************************************************/
60
61/*******************************************************************************************
62 * This structure defines a remote_busylock.
63 * - The <ticket> and <current> fields implement the ticket policy described above.
64 * - The <type> and <xlist> fields are used for debug. The type defines the lock usage,
65 *   as detailed in the kernel_config.h file.
66 * - The <save_sr> field is used to implement the critical section as decribed above.
67 ******************************************************************************************/
68
69typedef struct remote_busylock_s
70{
71        uint32_t            ticket;      /*! next free ticket index                           */
72    volatile uint32_t   current;     /*! current owner index                              */
73    uint32_t            type;        /*! lock type for debug                              */
74    reg_t               save_sr;     /*! SR value                                         */
75
76#if DEBUG_BUSYLOCK
77    xlist_entry_t       xlist;       /*! member of list of locks taken by same thread     */
78#endif
79
80}
81remote_busylock_t;
82
83/*******************************************************************************************
84 * This function initializes a remote busylock.
85 *******************************************************************************************
86 * @ lock_xp    : extended pointer on remote busylock.
87 * @ type       : lock type for debug.
88 ******************************************************************************************/
89void remote_busylock_init( xptr_t   lock_xp,
90                           uint32_t type );
91
92/*******************************************************************************************
93 * This blocking function uses a busy waiting strategy to acquire a remote_busylock.
94 * It makes an atomic increment on the "ticket" field to get a ticket value and increment
95 * the ticket allocator.
96 * Then it polls the "current" field until (current == ticket), and returns.
97 *******************************************************************************************
98 * @ lock_xp    : extended pointer on remote busylock
99 ******************************************************************************************/
100void remote_busylock_acquire( xptr_t   lock_xp );
101
102/*******************************************************************************************
103 * This function releases a busylock by incrementing the "current field".
104 *******************************************************************************************
105 * @ lock_xp       : extended pointer on remote busylock
106 ******************************************************************************************/
107void remote_busylock_release( xptr_t  lock_xp );
108
109#endif  /* _REMOTE_BUSYLOCK_H_ */
Note: See TracBrowser for help on using the repository browser.