source: trunk/kernel/libk/busylock.c @ 645

Last change on this file since 645 was 624, checked in by alain, 5 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: 3.8 KB
Line 
1/*
2 * busylock.c - local kernel-busy waiting lock implementation.
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-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <kernel_config.h>
25#include <hal_kernel_types.h>
26#include <hal_irqmask.h>
27#include <hal_special.h>
28#include <hal_atomic.h>
29#include <thread.h>
30#include <busylock.h>
31
32//////////////////////////////////////////////////////////////////////////////
33//                Extern global variables
34//////////////////////////////////////////////////////////////////////////////
35
36extern char               * lock_type_str[];    // allocated in kernel_init.c
37extern chdev_directory_t    chdev_dir;          // allocated in kernel_init.c
38
39//////////////////////////////////////
40void busylock_init( busylock_t * lock,
41                    uint32_t     type )
42{
43    lock->ticket  = 0;
44    lock->current = 0;
45    lock->type    = type;
46
47#if DEBUG_BUSYLOCK
48    xlist_entry_init( XPTR( local_cxy , &lock->xlist ) ); 
49#endif
50
51}
52
53//////////////////////////////////////////
54void busylock_acquire( busylock_t * lock )
55{
56    reg_t      save_sr;
57    thread_t * this = CURRENT_THREAD;
58
59    // enter critical section
60    hal_disable_irq( &save_sr );
61 
62    // get one free ticket and update ticket allocator
63    uint32_t ticket = hal_atomic_add( &lock->ticket , 1 );
64
65    // poll current until success
66    while( lock->current != ticket )  asm volatile ("nop");
67
68    // increment thread locks counter
69    this->busylocks++;
70
71    // save SR in lock descriptor
72    lock->save_sr = save_sr;
73
74    // memory barrier to update lock and thread state
75    hal_fence();
76
77#if DEBUG_BUSYLOCK
78if( lock->type != LOCK_CHDEV_TXT0 ) 
79{
80    // update thread list of busylocks
81    xptr_t root_xp = XPTR( local_cxy , &this->busylocks_root );
82    xlist_add_last( root_xp , XPTR( local_cxy , &lock->xlist ) );
83}
84#endif
85
86#if( DEBUG_BUSYLOCK & 1 )
87if( (lock->type != LOCK_CHDEV_TXT0) && 
88    (this->process->pid == DEBUG_BUSYLOCK_PID) &&
89    (this->trdid == DEBUG_BUSYLOCK_TRDID) )
90{
91    printk("\n[%s] thread[%x,%x] ACQUIRE lock %s\n",
92    __FUNCTION__, this->process->pid, this->trdid, lock_type_str[lock->type] );
93}
94#endif
95
96} // end busylock_acquire()
97
98//////////////////////////////////////////
99void busylock_release( busylock_t * lock )
100{
101    thread_t * this = CURRENT_THREAD;
102
103    // memory barrier to update the protected object
104    hal_fence();
105
106    // update lock state
107    lock->current++;
108
109    // decrement thread busylocks counter
110    this->busylocks--;
111
112    // memory barrier to update busylock and thread state
113    hal_fence();
114
115#if DEBUG_BUSYLOCK
116if( lock->type != LOCK_CHDEV_TXT0 ) 
117{
118    // remove lock from thread list of busylocks
119    xlist_unlink( XPTR( local_cxy , &lock->xlist ) );
120}
121#endif
122
123#if( DEBUG_BUSYLOCK & 1 )
124if( (lock->type != LOCK_CHDEV_TXT0) && 
125    (this->process->pid == DEBUG_BUSYLOCK_PID) &&
126    (this->trdid == DEBUG_BUSYLOCK_TRDID) )
127{
128    printk("\n[%s] thread[%x,%x] RELEASE lock %s\n",
129    __FUNCTION__, this->process->pid, this->trdid, lock_type_str[lock->type] );
130}
131#endif
132
133    // exit critical section
134    hal_restore_irq( lock->save_sr );
135 
136}  // end busylock_release()
137
138       
Note: See TracBrowser for help on using the repository browser.