source: trunk/kernel/libk/busylock.h @ 650

Last change on this file since 650 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.2 KB
RevLine 
[563]1/*
2 * busylock.h: local kernel busy-waiting lock definition.     
3 *
[624]4 * Authors  Alain Greiner (2016,2017,2018,2019)
[563]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 _BUSYLOCK_H_
25#define _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
34 * a shared object located in a given cluster, made by thread(s) running in same cluster.
35 * It uses a busy waiting policy when the lock is taken by another thread, and should
[624]36 * be used to execute very short actions, such as accessing basic allocators or higher
[623]37 * level synchronisation objects (barriers, queuelocks, or rwlocks).
[563]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 *
[624]43 * - To release the lock, the owner thread increments the "current" value.
[563]44 *
[624]45 * - When a thread takes a busylock, it enters a critical section: the acquire()
[563]46 *   function disables the IRQs, takes the lock, increments the thread busylocks counter,
[624]47 *   save the SR in lock descriptor and returns.
[563]48 *
[624]49 * - The release() function releases the lock, decrements the thread busylock
50 *   counter, restores the SR to exit the critical section, and returns.
[563]51 *
[624]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.
[563]59 ******************************************************************************************/
60
61/*******************************************************************************************
62 * This structure defines a busylock.
[624]63 * The <xlist> field is only used when DEBUG_BUSYLOCK is set.
64 * The <type> field defines the lock usage as detailed in the kernel_config.h file.
[563]65******************************************************************************************/
66
67typedef struct busylock_s
68{
69        uint32_t            ticket;      /*! next free ticket index                           */
70    volatile uint32_t   current;     /*! current owner index                              */
71    uint32_t            type;        /*! lock type for debug                              */
72    reg_t               save_sr;     /*! SR value                                         */
73
74#if DEBUG_BUSYLOCK
75    xlist_entry_t       xlist;       /*! member of list of locks taken by same thread     */
76#endif
77
78}
79busylock_t;
80
81/*******************************************************************************************
82 * This function initializes a busylock.
83 *******************************************************************************************
84 * @ lock    : local pointer on busylock.
85 * @ type    : lock  type for debug.
86 ******************************************************************************************/
87void busylock_init( busylock_t * lock,
88                    uint32_t    type );
89
90/*******************************************************************************************
91 * This blocking function uses a busy waiting strategy to acquire a busylock.
92 * It makes an atomic increment on the "ticket" field to get a ticket value and increment
93 * the ticket allocator.
94 * Then it polls the "current" field until (current == ticket), and returns.
95 *******************************************************************************************
96 * @ lock    : local pointer on busylock.
97 ******************************************************************************************/
98void busylock_acquire( busylock_t * lock );
99
100/*******************************************************************************************
101 * This function releases a busylock by incrementing the "current" field.
102 *******************************************************************************************
103 * @ lock    : local pointer on busylock.
104 ******************************************************************************************/
105void busylock_release( busylock_t * lock );
106
107#endif  /* _BUSYLOCK_H_ */
Note: See TracBrowser for help on using the repository browser.