Ignore:
Timestamp:
May 3, 2017, 1:23:24 PM (7 years ago)
Author:
alain
Message:

Bugs fix.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/thread.c

    r5 r14  
    2424 */
    2525
    26 #include <almos_config.h>
     26#include <kernel_config.h>
    2727#include <hal_types.h>
    2828#include <hal_context.h>
     
    7676
    7777/////////////////////////////////////////////////////////////////////////////////////
    78 // This static function makes the actual allocation and initialisation for a thread
    79 // descriptor. It is called by the three functions:
     78// This static function allocates physical memory for a thread descriptor.
     79// It can be called by the three functions:
    8080// - thread_user_create()
    81 // - thread_user_copy()
     81// - thread_user_fork()
    8282// - thread_kernel_create()
    8383/////////////////////////////////////////////////////////////////////////////////////
    84 // @ new_thread : buffer for new thread pointer.
    85 // @ process    : local pointer on process descriptor.
    86 // @ type       : thread type.
    87 // @ func       : local pointer on thread entry function.
    88 // @ args       : local pointer on thread entry function arguments.
    89 // @ core_lid   : target core local index.
     84// @ return pointer on thread descriptor if success / return NULL if failure.
    9085/////////////////////////////////////////////////////////////////////////////////////
    91 static error_t thread_create( thread_t     ** new_thread,
    92                               process_t     * process,
    93                               thread_type_t   type,
    94                               void          * func,
    95                               void          * args,
    96                               lid_t           core_lid,
    97                               intptr_t        u_stack_base,
    98                               uint32_t        u_stack_size )
    99 {
    100     error_t        error;
    101         thread_t     * thread;     // pointer on thread descriptor
     86static thread_t * thread_alloc()
     87{
    10288        page_t       * page;       // pointer on page descriptor containing thread descriptor
    10389        kmem_req_t     req;        // kmem request
    104     trdid_t        trdid;      // allocated thread identifier
    105 
    106         cluster_t    * local_cluster = LOCAL_CLUSTER;
    10790
    10891        // allocates memory for thread descriptor + kernel stack
    10992        req.type  = KMEM_PAGE;
    110         req.size  = CONFIG_THREAD_PAGE_ORDER;
     93        req.size  = CONFIG_THREAD_DESC_ORDER;
    11194        req.flags = AF_KERNEL | AF_ZERO;
    11295        page      = kmem_alloc( &req );
    113         if( page == NULL ) return ENOMEM;
    114 
    115     // get pointer on new thread descriptor
    116         thread = (thread_t *)ppm_page2base( page );
    117 
    118     // register new thread in local process descriptor, and get a TRDID
     96
     97    // return pointer on new thread descriptor
     98        if( page == NULL )
     99    {
     100        printk("\n[ERROR] in %s : no memory for thread descriptor\n", __FUNCTION__ );
     101        return NULL;
     102    }
     103    else
     104    {
     105        return (thread_t *)ppm_page2base( page );
     106    }
     107}  // end thread_alloc()
     108
     109/////////////////////////////////////////////////////////////////////////////////////
     110// This static function initializes a thread descriptor (kernel or user).
     111// It can be called by the four functions:
     112// - thread_user_create()
     113// - thread_user_fork()
     114// - thread_kernel_create()
     115// - thread_user_init()
     116/////////////////////////////////////////////////////////////////////////////////////
     117// @ thread       : pointer on thread descriptor
     118// @ process      : pointer on process descriptor.
     119// @ type         : thread type.
     120// @ func         : pointer on thread entry function.
     121// @ args         : pointer on thread entry function arguments.
     122// @ core_lid     : target core local index.
     123// @ u_stack_base : stack base (user thread only)
     124// @ u_stack_size : stack base (user thread only)
     125/////////////////////////////////////////////////////////////////////////////////////
     126static error_t thread_init( thread_t      * thread,
     127                            process_t     * process,
     128                            thread_type_t   type,
     129                            void          * func,
     130                            void          * args,
     131                            lid_t           core_lid,
     132                            intptr_t        u_stack_base,
     133                            uint32_t        u_stack_size )
     134{
     135    error_t        error;
     136    trdid_t        trdid;      // allocated thread identifier
     137
     138        cluster_t    * local_cluster = LOCAL_CLUSTER;
     139
     140    // register new thread in process descriptor, and get a TRDID
    119141    spinlock_lock( &process->th_lock );
    120142    error = process_register_thread( process, thread , &trdid );
     
    123145    if( error )
    124146    {
    125         // release allocated memory for thread descriptor
    126             req.type  = KMEM_PAGE;
    127         req.ptr   = page;
    128         kmem_free( &req );
    129         return EAGAIN;
    130     }
    131  
     147        printk("\n[ERROR] in %s : cannot get TRDID\n", __FUNCTION__ );
     148        return EINVAL;
     149    }
     150
    132151        // Initialize new thread descriptor
    133152    thread->trdid           = trdid;
     
    138157        thread->core            = &local_cluster->core_tbl[core_lid];
    139158        thread->process         = process;
    140     thread->page            = page;
    141159
    142160    thread->local_locks     = 0;
     
    149167    thread->u_stack_size    = u_stack_size;
    150168    thread->k_stack_base    = (intptr_t)thread;     
    151     thread->k_stack_size    = CONFIG_PPM_PAGE_SIZE << CONFIG_THREAD_PAGE_ORDER;
     169    thread->k_stack_size    = CONFIG_THREAD_DESC_SIZE;
    152170
    153171    thread->entry_func      = func;         // thread entry point
     
    182200    sched_register_thread( thread->core , thread );
    183201
    184     *new_thread = thread;
    185202        return 0;
    186 } // end thread_create()
     203
     204} // end thread_init()
    187205
    188206
     
    197215    process_t    * process;      // pointer to local process descriptor
    198216    lid_t          core_lid;     // selected core local index
    199 
    200     thread_dmsg("\n[INFO] %s : enters\n",
    201                 __FUNCTION__ );
     217        kmem_req_t     req;          // kmem request (for release)
     218
     219    thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ );
    202220
    203221        cluster_t    * local_cluster = LOCAL_CLUSTER;
     
    214232    if( process == NULL ) return ENOMEM;
    215233
    216     // make allocation / initialisation
    217     error = thread_create( &thread,
    218                            process,
    219                            THREAD_USER,
    220                            attr->entry_func,
    221                            attr->entry_args,
    222                            core_lid,
    223                            u_stack_base,
    224                            u_stack_size );
    225     if( error ) return ENOMEM;
    226 
    227     // set LOADABLE flag / set ATTACHED flag if required
     234    // allocates memory tor thread descriptor
     235    thread = thread_alloc();
     236
     237    if( thread == NULL ) return ENOMEM;
     238
     239    // initializes thread descriptor
     240    error = thread_init( thread,
     241                         process,
     242                         THREAD_USER,
     243                         attr->entry_func,
     244                         attr->entry_args,
     245                         core_lid,
     246                         u_stack_base,
     247                         u_stack_size );
     248
     249    if( error )  // release allocated memory for thread descriptor
     250    {
     251            req.type  = KMEM_PAGE;
     252        req.ptr   = ppm_base2page( thread );
     253        kmem_free( &req );
     254        return EINVAL;
     255    }
     256
     257    // set LOADABLE flag
    228258    thread->flags = THREAD_FLAG_LOADABLE;
     259
     260    // set DETACHED flag if required
    229261    if( attr->flags & PT_FLAG_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;
    230262
     
    242274    *new_thread = thread;
    243275        return 0;
     276
    244277} // end thread_user_create()
    245278
     
    252285{
    253286    error_t        error;
    254         thread_t     * new;          // pointer on thread descriptor
     287        thread_t     * thread;       // pointer on new thread descriptor
    255288    lid_t          core_lid;     // selected core local index
    256 
    257     thread_dmsg("\n[INFO] %s : enters\n",
    258                 __FUNCTION__ );
     289        kmem_req_t     req;          // kmem request (for release)
     290
     291    thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ );
    259292
    260293    // select a target core in local cluster
     
    264297    thread_t * this = CURRENT_THREAD;
    265298
    266     // make allocation / initialisation
    267     error = thread_create( &new,
    268                            process,
    269                            THREAD_USER,
    270                            this->entry_func,
    271                            this->entry_args,
    272                            core_lid,
    273                            u_stack_base,
    274                            u_stack_size );
     299    // allocated memory for new thread descriptor
     300    thread = thread_alloc();
     301
     302    if( thread == NULL ) return ENOMEM;
     303
     304    // initializes thread descriptor
     305    error = thread_init( thread,
     306                         process,
     307                         THREAD_USER,
     308                         this->entry_func,
     309                         this->entry_args,
     310                         core_lid,
     311                         u_stack_base,
     312                         u_stack_size );
     313
     314    if( error ) // release allocated memory for thread descriptor
     315    {
     316            req.type  = KMEM_PAGE;
     317        req.ptr   = ppm_base2page( thread );
     318        kmem_free( &req );
     319        return EINVAL;
     320    }
     321
     322    // set ATTACHED flag if set in this thread
     323    if( this->flags & THREAD_FLAG_DETACHED ) thread->flags = THREAD_FLAG_DETACHED;
     324
     325    // allocate & initialise CPU context from calling thread
     326        error = hal_cpu_context_copy( thread , this );
    275327    if( error ) return ENOMEM;
    276328
    277     // set ATTACHED flag if set in this thread
    278     if( this->signals & THREAD_FLAG_DETACHED ) new->signals = THREAD_FLAG_DETACHED;
    279 
    280     // allocate & initialise CPU context from calling thread
    281         error = hal_cpu_context_copy( new , this );
     329    // allocate & initialise FPU context from calling thread
     330        error = hal_fpu_context_copy( thread , this );
    282331    if( error ) return ENOMEM;
    283332
    284     // allocate & initialise FPU context from calling thread
    285         error = hal_fpu_context_copy( new , this );
    286     if( error ) return ENOMEM;
    287 
    288333    thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n",
    289                  __FUNCTION__, new->trdid, process->pid, core_lid, local_cxy );
    290 
    291     *new_thread = new;
     334                 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy );
     335
     336    *new_thread = thread;
    292337        return 0;
    293338
     
    304349{
    305350    error_t        error;
    306         thread_t     * new;        // pointer on new thread descriptor
    307 
    308     thread_dmsg("\n[INFO] %s : enters for %s in cluster %x\n",
     351        thread_t     * thread;       // pointer on new thread descriptor
     352        kmem_req_t     req;          // kmem request (for release)
     353
     354    thread_dmsg("\n[INFO] %s : enters for type %s in cluster %x\n",
    309355                __FUNCTION__ , thread_type_str( type ) , local_cxy );
    310356
     
    316362            __FUNCTION__ , "illegal core_lid" );
    317363
    318     // make allocation / initialisation
    319     error = thread_create( &new,
    320                            &process_zero,
    321                            type,
    322                            func,
    323                            args,
    324                            core_lid,
    325                            0 , 0 );  // no user stack for a kernel thread
    326     if( error )
    327     {
    328         printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ );
    329         return ENOMEM;
    330     }
     364    // allocated memory for new thread descriptor
     365    thread = thread_alloc();
     366
     367    if( thread == NULL ) return ENOMEM;
     368
     369    // initializes thread descriptor
     370    error = thread_init( thread,
     371                         &process_zero,
     372                         type,
     373                         func,
     374                         args,
     375                         core_lid,
     376                         0 , 0 );  // no user stack for a kernel thread
     377
     378    if( error ) // release allocated memory for thread descriptor
     379    {
     380            req.type  = KMEM_PAGE;
     381        req.ptr   = ppm_base2page( thread );
     382        kmem_free( &req );
     383        return EINVAL;
     384    }
     385
    331386
    332387    // allocate & initialise CPU context
    333         hal_cpu_context_create( new );
    334 
    335     thread_dmsg("\n[INFO] %s : sucessfully exit / trdid = %x / core = %d\n",
    336                  __FUNCTION__ , new->trdid , core_lid );
    337 
    338     *new_thread = new;
     388        hal_cpu_context_create( thread );
     389
     390    thread_dmsg("\n[INFO] %s : exit in cluster %x / trdid = %x / core_lid = %d\n",
     391                 __FUNCTION__ , local_cxy , thread->trdid , core_lid );
     392
     393    *new_thread = thread;
    339394        return 0;
    340395
    341396} // end thread_kernel_create()
    342397
     398///////////////////////////////////////////////////
     399error_t thread_kernel_init( thread_t      * thread,
     400                            thread_type_t   type,
     401                            void          * func,
     402                            void          * args,
     403                                            lid_t           core_lid )
     404{
     405    assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) ||
     406              (type == THREAD_IDLE)   || (type == THREAD_DEV) ) ,
     407              __FUNCTION__ , "illegal thread type" );
     408
     409    if( core_lid >= LOCAL_CLUSTER->cores_nr )
     410    {
     411        printk("\n[PANIC] in %s : illegal core_lid / cores = %d / lid = %d / cxy = %x\n",
     412               __FUNCTION__ , LOCAL_CLUSTER->cores_nr , core_lid , local_cxy );
     413        hal_core_sleep();
     414    }
     415
     416    error_t  error = thread_init( thread,
     417                                  &process_zero,
     418                                  type,
     419                                  func,
     420                                  args,
     421                                  core_lid,
     422                                  0 , 0 );   // no user stack for a kernel thread
     423
     424    // allocate & initialize CPU context if success
     425    if( error == 0 ) hal_cpu_context_create( thread );
     426     
     427    return error;
     428
     429}  // end thread_kernel_init()
    343430
    344431///////////////////////////////////////////////////////////////////////////////////////
     
    592679
    593680
    594 /////////////////////////
    595 void * thread_idle_func()
    596 {
     681///////////////////////
     682void thread_idle_func()
     683{
     684    lid_t  lid = CURRENT_CORE->lid;
     685
    597686    while( 1 )
    598687    {
    599         thread_dmsg("\n[INFO] %s : core %d in cluster %x goes to sleeping state at cycle\n",
    600                     __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() );
     688        thread_dmsg("\n[INFO] %s : core[%x][%d] goes to sleep at cycle %d\n",
     689                    __FUNCTION__ , local_cxy , lid , hal_time_stamp() );
    601690
    602691        // force core to sleeping state
    603692        hal_core_sleep();
    604693
    605         thread_dmsg("\n[INFO] %s : core %d in cluster %x wake up at cycle %d\n",
    606                     __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() );
    607 
    608         // force scheduling at wake-up
     694        thread_dmsg("\n[INFO] %s : core[%x][%d] wake up at cycle %d\n",
     695                    __FUNCTION__ , local_cxy , lid , hal_time_stamp() );
     696
     697                // acknowledge IRQ
     698        dev_icu_irq_handler();
     699
     700        // force scheduling
    609701        sched_yield();
    610702   }
Note: See TracChangeset for help on using the changeset viewer.