source: soft/giet_vm/giet_kernel/ctx_handler.c @ 718

Last change on this file since 718 was 714, checked in by alain, 9 years ago

Introduce the _sys_fbf_size() function.
Modify the _sys_fbf_alloc() / _sys_fbf_release() functions
to allow all threads of a given vspace to access the frame buffer.
(replace the lock by a multi-threads allocator.

  • Property svn:executable set to *
File size: 7.1 KB
RevLine 
[294]1//////////////////////////////////////////////////////////////////////////////////
[258]2// File     : ctx_handler.c
3// Date     : 01/04/2012
4// Authors  : alain greiner & joel porquet
5// Copyright (c) UPMC-LIP6
[294]6//////////////////////////////////////////////////////////////////////////////////
[258]7
[440]8#include <ctx_handler.h>
[695]9#include <sys_handler.h>
[258]10#include <giet_config.h>
[709]11#include <fat32.h>
[528]12#include <hard_config.h>
[440]13#include <utils.h>
[459]14#include <tty0.h>
[258]15#include <xcu_driver.h>
[709]16#include <bdv_driver.h>
[258]17
[528]18/////////////////////////////////////////////////////////////////////////////////
19//     Extern variables and functions
20/////////////////////////////////////////////////////////////////////////////////
21
22// defined in giet_kernel/switch.s file
[709]23extern void _thread_switch( thread_context_t* , thread_context_t* );
[258]24
[528]25// allocated in boot.c or kernel_init.c files
26extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
27
[709]28// allocated in kernel_init.c file
29extern fat_desc_t  _fat;
[702]30
[709]31//////////////////////////////////////////////////////////////////
32// This function is called by the _ctx_switch() function.
33// It desactivates a thread that received a KILL signal.
34// We must release all ressources allocated to the thread
35// before the actual desactivation, that uses NORUN_MASK_THREAD.
36//////////////////////////////////////////////////////////////////
37static void _ctx_kill_thread( unsigned int x,
38                              unsigned int y,
39                              unsigned int p,
40                              unsigned int ltid )
[695]41{
42    // get scheduler address
[709]43    static_scheduler_t* psched = _schedulers[x][y][p];
[695]44
[709]45    // pretend the thread to kill is the currently scheduled thread
46    // (required by the _sys_***_release() calls)
47    unsigned int cur_thread = psched->current;
[697]48    psched->current = ltid;
49
[709]50    // release BDV lock if taken and reset BDV peripheral
51    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_BDV ) 
[695]52    {
[709]53        _bdv_set_register( BLOCK_DEVICE_STATUS , 0 );
54        _spin_lock_release( &_bdv_lock );
[695]55    }
56
[709]57    // release FAT lock if taken
58    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FAT ) 
59    {
[714]60       
[709]61        _spin_lock_release( &_fat.fat_lock );
62    }
63
[714]64    // release FBF lock if taken
65    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FBF ) 
66    {
67        _sys_fbf_release();
68    }
69
[709]70    // release private TTY terminal if required
71    if ( psched->context[ltid].slot[CTX_TTY_ID] < NB_TTY_CHANNELS ) 
72        _sys_tty_release(); 
73
[695]74    // release private TIM channel if required
[709]75
76    if ( psched->context[ltid].slot[CTX_TIM_ID] < NB_TIM_CHANNELS )
[695]77    {
78        _sys_tim_release();
79    }
80
[709]81    // release private NIC_RX and CMA_RX channels if required
82    if ( psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
[695]83    {
84        _sys_nic_release( 1 );
85    }
86
[709]87    // release private NIC_TX and CMA_TX channels if required
88    if ( psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
[695]89    {
90        _sys_nic_release( 0 );
91    }
92
[700]93    // release private FBF_CMA channel if required
[709]94    if ( psched->context[ltid].slot[CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
[700]95    {
96        _sys_fbf_cma_release();
97    }
98
[709]99    // restore scheduled thread index
100    psched->current = cur_thread;
[697]101
[709]102    // set NORUN_MASK_THREAD bit to desactivate the target thread
103    psched->context[ltid].slot[CTX_NORUN_ID] = NORUN_MASK_THREAD;
[695]104
[709]105} // end _ctx_kill_thread()
[695]106
[702]107
[440]108//////////////////
[258]109void _ctx_switch() 
110{
[294]111    unsigned int gpid       = _get_procid();
[428]112    unsigned int cluster_xy = gpid >> P_WIDTH;
[709]113    unsigned int x          = cluster_xy >> Y_WIDTH;
114    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
115    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
[294]116
[709]117    unsigned int ltid;     // index for loops on threads in scheduler
118
119    // get calling thread scheduler address
[258]120    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
121
[709]122    // get number of threads allocated to scheduler
123    unsigned int threads = psched->threads;
[258]124
[709]125    // get current thread ltid
126    unsigned int curr_thread_id = psched->current;
[258]127
[709]128    // first loop on threads: handle all pending KILL signals
129    for ( ltid = 0 ; ltid < threads ; ltid++ )
[258]130    {
[709]131        if ( psched->context[ltid].slot[CTX_SIGS_ID] & SIGS_MASK_KILL )
[695]132        {
[709]133            // acknowledge KILL signal
134            _atomic_and( &psched->context[ltid].slot[CTX_SIGS_ID], ~SIGS_MASK_KILL );
[706]135
[709]136            // desactivate the killed thread
137            _ctx_kill_thread( x , y , p , ltid );
[696]138        }
[709]139    }
[695]140
[709]141    // second loop: select next thread using a round-robin policy
142    unsigned int next_thread_id;
143    unsigned int found = 0;
144    for ( ltid = curr_thread_id + 1 ; ltid < (curr_thread_id + 1 + threads) ; ltid++ ) 
145    {
146        next_thread_id = ltid % threads;
147
148        // test if the thread is runable
149        if ( psched->context[next_thread_id].slot[CTX_NORUN_ID] == 0 )
[258]150        {
151            found = 1;
152            break;
153        }
154    }
155
[709]156    // launch idle_thread if no runable thread
157    if ( found == 0 ) next_thread_id = IDLE_THREAD_INDEX;
[258]158
[709]159    if ( curr_thread_id != next_thread_id )  // actual thread switch required
160    {
161
162#if GIET_DEBUG_SWITCH
[294]163unsigned int x = cluster_xy >> Y_WIDTH;
164unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[709]165if ( (_get_proctime() > GIET_DEBUG_SWITCH) && (x == 0) && (y == 0) && (p == 0) )
[528]166_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
[709]167        curr_thread_id, next_thread_id, x, y , p, _get_proctime() );
[258]168#endif
169
[709]170        thread_context_t* curr_ctx_vaddr = &(psched->context[curr_thread_id]);
171        thread_context_t* next_ctx_vaddr = &(psched->context[next_thread_id]);
[275]172
[528]173        // reset TICK timer counter.
[709]174        _xcu_timer_reset_cpt( cluster_xy, p );
[275]175
[709]176        // set current thread index
177        psched->current = next_thread_id;
[275]178
179        // makes context switch
[709]180        _thread_switch( curr_ctx_vaddr , next_ctx_vaddr );
[258]181    }
182} //end _ctx_switch()
183
[528]184
[709]185///////////////////
186void _idle_thread() 
[258]187{
[391]188    unsigned int gpid       = _get_procid();
[428]189    unsigned int cluster_xy = gpid >> P_WIDTH;
[391]190    unsigned int x          = cluster_xy >> Y_WIDTH;
191    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[440]192    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
[391]193
[258]194    while(1)
195    {
[391]196        // initialize counter
[709]197        unsigned int count = GIET_IDLE_THREAD_PERIOD;
[275]198
[294]199        // decounting loop
[258]200        asm volatile(
201                "move   $3,   %0              \n"
[709]202                "_idle_thread_loop:             \n"
[258]203                "addi   $3,   $3,   -1        \n"
[709]204                "bnez   $3,   _idle_thread_loop \n"
[258]205                "nop                          \n"
206                :
207                : "r"(count)
208                : "$3" ); 
209
[294]210        // warning message
[528]211        _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d",
212                x , y , p , _get_proctime() );
[258]213    }
214} // end ctx_idle()
215
216
[440]217////////////////
[258]218void _ctx_eret() 
219{
220    asm volatile("eret");
221}
222
223
224// Local Variables:
225// tab-width: 4
226// c-basic-offset: 4
227// c-file-offsets:((innamespace . 0)(inline-open . 0))
228// indent-tabs-mode: nil
229// End:
230// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
231
Note: See TracBrowser for help on using the repository browser.