Ignore:
Timestamp:
May 3, 2018, 5:51:22 PM (4 years ago)
Author:
alain
Message:

1/ Fix a bug in the Multithreaded "sort" applicationr:
The pthread_create() arguments must be declared as global variables.
2/ The exit syscall can be called by any thread of a process..

File:
1 edited

Legend:

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

    r438 r440  
    106106    char        rx_path[40];
    107107    char        tx_path[40];
     108    xptr_t      file_xp;
    108109    xptr_t      chdev_xp;
    109110    chdev_t *   chdev_ptr;
     
    179180        assert( (stdin_id == 0) , __FUNCTION__ , "stdin index must be 0" );
    180181
     182#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     183cycle = (uint32_t)hal_get_cycles();
     184if( DEBUG_PROCESS_REFERENCE_INIT )
     185printk("\n[DBG] %s : thread %x / stdin open for process %x / cycle %d\n",
     186__FUNCTION__ , CURRENT_THREAD , pid , cycle );
     187#endif
     188
    181189        // create stdout pseudo file         
    182190        error = vfs_open( process,
     
    190198        assert( (stdout_id == 1) , __FUNCTION__ , "stdout index must be 1" );
    191199
     200#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     201cycle = (uint32_t)hal_get_cycles();
     202if( DEBUG_PROCESS_REFERENCE_INIT )
     203printk("\n[DBG] %s : thread %x / stdout open for process %x / cycle %d\n",
     204__FUNCTION__ , CURRENT_THREAD , pid , cycle );
     205#endif
     206
    192207        // create stderr pseudo file         
    193208        error = vfs_open( process,
     
    201216        assert( (stderr_id == 2) , __FUNCTION__ , "stderr index must be 2" );
    202217
     218#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
     219cycle = (uint32_t)hal_get_cycles();
     220if( DEBUG_PROCESS_REFERENCE_INIT )
     221printk("\n[DBG] %s : thread %x / stderr open for process %x / cycle %d\n",
     222__FUNCTION__ , CURRENT_THREAD , pid , cycle );
     223#endif
     224
    203225    }
    204226    else                                            // normal user process
    205227    {
     228        // get extended pointer on stdin pseudo file in model process
     229        file_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy , &model_ptr->fd_array.array[0] ) );
     230
    206231        // get extended pointer on model process TXT chdev
    207         chdev_xp = chdev_from_file( model_ptr->fd_array.array[0] );
     232        chdev_xp = chdev_from_file( file_xp );
    208233 
    209234        // get cluster and local pointer on chdev
     
    374399uint32_t cycle = (uint32_t)hal_get_cycles();
    375400if( DEBUG_PROCESS_DESTROY )
    376 printk("\n[DBG] %s : thread %x enter to destroy process %x (pid = %x) / cycle %d\n",
    377 __FUNCTION__ , CURRENT_THREAD , process, pid , cycle );
     401printk("\n[DBG] %s : thread %x enter in cluster %x / pid %x / process %x / cycle %d\n",
     402__FUNCTION__ , CURRENT_THREAD , pid , process , cycle );
    378403#endif
    379404
     
    401426    }
    402427
    403     // release the process PID to cluster manager
    404     cluster_pid_release( pid );
     428    // release the process PID to cluster manager if owner cluster
     429    if( CXY_FROM_PID( pid ) == local_cxy ) cluster_pid_release( pid );
    405430
    406431    // FIXME close all open files and update dirty [AG]
     
    507532    XLIST_FOREACH( root_xp , iter_xp )
    508533    {
     534        // atomically increment responses counter
     535        hal_atomic_add( (void *)&rpc.responses , 1 );
     536
     537        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
     538        process_cxy = GET_CXY( process_xp );
    509539
    510540#if DEBUG_PROCESS_SIGACTION
     
    513543__FUNCTION__ , process_action_str( action_type ) , pid , process_cxy );
    514544#endif
    515         // atomically increment responses counter
    516         hal_atomic_add( (void *)&rpc.responses , 1 );
    517 
    518         process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
    519         process_cxy = GET_CXY( process_xp );
    520 
    521545        // call RPC in target cluster
    522546        rpc_process_sigaction_client( process_cxy , &rpc );
     
    529553    hal_restore_irq( save_sr);
    530554
    531     // client deschedule : will be unblocked by the last RPC server thread
     555    // client thread deschedule : will be unblocked by the last RPC server thread
    532556    sched_yield("blocked on rpc_process_sigaction");
    533557
     
    542566
    543567/////////////////////////////////////////////////
    544 void process_block_threads( process_t * process )
     568void process_block_threads( process_t * process,
     569                            xptr_t      client_xp )
    545570{
    546571    thread_t          * target;         // pointer on target thread
     
    567592    spinlock_lock( &process->th_lock );
    568593
    569     // loop to block all threads but the main thread
     594    // loop on target process local threads
    570595    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    571596    for( ltid = 0 , count = 0 , ack_count = 0 ; count < process->th_nr ; ltid++ )
     
    577602            count++;
    578603
    579             // main thread should not be deleted
    580             if( (ltid != 0) || (owner_cxy != local_cxy) )
     604            // main thread and client thread should not be blocked
     605            if( ((ltid != 0) || (owner_cxy != local_cxy)) &&         // not main thread
     606                (client_xp) != XPTR( local_cxy , target ) )          // not client thread
    581607            {
    582608                // set the global blocked bit in target thread descriptor.
     
    626652}  // end process_block_threads()
    627653
    628 ///////////////////////////////////////////////////
    629 void process_unblock_threads( process_t * process )
    630 {
    631     thread_t          * target;        // pointer on target thead
     654/////////////////////////////////////////////////
     655void process_delete_threads( process_t * process,
     656                             xptr_t      client_xp )
     657{
    632658    thread_t          * this;          // pointer on calling thread
     659    thread_t          * target;        // local pointer on target thread
     660    xptr_t              target_xp;     // extended pointer on target thread
     661    cxy_t               owner_cxy;     // owner process cluster
    633662    uint32_t            ltid;          // index in process th_tbl
    634     uint32_t            count;         // requests counter
     663    uint32_t            count;         // threads counter
    635664
    636665    // get calling thread pointer
    637666    this = CURRENT_THREAD;
     667
     668    // get target process owner cluster
     669    owner_cxy = CXY_FROM_PID( process->pid );
    638670
    639671#if DEBUG_PROCESS_SIGACTION
     
    647679    spinlock_lock( &process->th_lock );
    648680
    649     // loop on process threads to unblock all threads
     681    // loop on target process local threads                       
    650682    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    651     for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
     683    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
    652684    {
    653685        target = process->th_tbl[ltid];
    654686
    655         if( target != NULL )             // thread found
     687        if( target != NULL )    // valid thread 
    656688        {
    657689            count++;
    658 
    659             // reset the global blocked bit in target thread descriptor.
    660             thread_unblock( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL );
     690            target_xp = XPTR( local_cxy , target );
     691
     692            // main thread and client thread should not be blocked
     693            if( ((ltid != 0) || (owner_cxy != local_cxy)) &&         // not main thread
     694                (client_xp) != target_xp )                           // not client thread
     695            {
     696                // mark target thread for delete and block it
     697                thread_delete( target_xp , process->pid , false );   // not forced
     698            }
    661699        }
    662700    }
     
    672710#endif
    673711
    674 }  // end process_unblock_threads()
    675 
    676 //////////////////////////////////////////////////
    677 void process_delete_threads( process_t * process )
    678 {
    679     thread_t          * target;        // pointer on target thread
     712}  // end process_delete_threads()
     713
     714///////////////////////////////////////////////////
     715void process_unblock_threads( process_t * process )
     716{
     717    thread_t          * target;        // pointer on target thead
     718    thread_t          * this;          // pointer on calling thread
    680719    uint32_t            ltid;          // index in process th_tbl
    681     uint32_t            count;         // threads counter
     720    uint32_t            count;         // requests counter
     721
     722    // get calling thread pointer
     723    this = CURRENT_THREAD;
    682724
    683725#if DEBUG_PROCESS_SIGACTION
     
    685727if( DEBUG_PROCESS_SIGACTION < cycle )
    686728printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n",
    687 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
     729__FUNCTION__ , this , process->pid , local_cxy , cycle );
    688730#endif
    689731
     
    691733    spinlock_lock( &process->th_lock );
    692734
    693     // loop to set the REQ_DELETE flag on all threads but the main
     735    // loop on process threads to unblock all threads
    694736    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    695     for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
     737    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
    696738    {
    697739        target = process->th_tbl[ltid];
    698740
    699         if( target != NULL )
     741        if( target != NULL )             // thread found
    700742        {
    701743            count++;
    702            
    703             thread_kill( XPTR( local_cxy , target ),
    704                          false,                       // is_exit
    705                          true );                      // is_forced
     744
     745            // reset the global blocked bit in target thread descriptor.
     746            thread_unblock( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL );
    706747        }
    707748    }
     
    714755if( DEBUG_PROCESS_SIGACTION < cycle )
    715756printk("\n[DBG] %s : thread %x exit for process %x in cluster %x / cycle %d\n",
    716 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
    717 #endif
    718 
    719 }  // end process_delete_threads()
     757__FUNCTION__ , this , process->pid , local_cxy , cycle );
     758#endif
     759
     760}  // end process_unblock_threads()
    720761
    721762///////////////////////////////////////////////
     
    749790
    750791    // allocate memory for a new local process descriptor
    751     // and initialise it from reference cluster if required
     792    // and initialise it from reference cluster if not found
    752793    if( !found )
    753794    {
     
    765806        if( error ) return NULL;
    766807    }
     808
     809#if DEBUG_PROCESS_GET_LOCAL_COPY
     810uint32_t cycle = (uint32_t)hal_get_cycles();
     811if( DEBUG_PROCESS_GET_LOCAL_COPY < cycle )
     812printk("\n[DBG] %s : enter in cluster %x / pid %x / process %x / cycle %d\n",
     813__FUNCTION__ , local_cxy , pid , process_ptr , cycle );
     814#endif
    767815
    768816    return process_ptr;
     
    10321080    // check parent process is the reference process
    10331081    ref_xp = hal_remote_lwd( XPTR( parent_process_cxy , &parent_process_ptr->ref_xp ) );
    1034 
    1035 printk("\n@@@ %s : parent_cxy = %x / parent_ptr = %x / ref_cxy = %x / ref_ptr = %x\n",
    1036 __FUNCTION__, parent_process_cxy, parent_process_ptr, GET_CXY( ref_xp ), GET_PTR( ref_xp ) );
    10371082
    10381083    assert( (parent_process_xp == ref_xp ) , __FUNCTION__ ,
Note: See TracChangeset for help on using the changeset viewer.