Changeset 440 for trunk/user


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..

Location:
trunk/user
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/user/init/Makefile

    r439 r440  
    44
    55-include ../../params-soft.mk
     6
    67ifeq ($(ARCH_NAME),)
    78$(error Please define in ARCH_NAME parameter in params-soft.mk!)
     
    1011OBJS = build/init.o
    1112
    12 INCLUDES = -I.                   \
    13            -I../..               \
    14            -I$(LIBC_INCLUDE)/    \
    15            -I$(LIBPTHREAD_INCLUDE) \
     13INCLUDES = -I.                     \
     14           -I../..                 \
     15           -I$(LIBC_INCLUDE)/      \
     16           -I$(LIBPTHREAD_INCLUDE)
    1617
    1718compile : dirs build/init.elf
     
    2829
    2930clean:
    30         rm -rf build/*.o build/*.elf build/*.o.txt
     31        rm -rf build/*.o  build/*.elf  build/*.txt
    3132
    3233.PHONY: dirs clean
  • trunk/user/init/init.c

    r438 r440  
    77// It uses the fork/exec syscalls to create N KSH child processes
    88// (one child process per user terminal).
    9 // It includes the hard_config.h file to get th NB_TXT_CHANNELS parameter.
    10 //
    11 // TODO : Register the PIDs for all KSH[i] in a ksh_pid[] array.
    129// Then calls the wait() function to block, and reactivate any child KSH process
    1310// that has been deleted, using a new fork/exec.
     11// It includes the hard_config.h file to get th NB_TXT_CHANNELS parameter.
    1412///////////////////////////////////////////////////////////////////////////////////////
    1513
     
    1917#include <stdio.h>
    2018#include <pthread.h>
     19
     20#define DEBUG_INIT 1
     21
     22// TODO make the cxy computation portable [AG]
     23#define CXY_FROM_XY( x , y )  ((x<<4) + y)
    2124
    2225//////////
     
    4346        {
    4447            // INIT display error message 
    45             snprintf( string , 64 , "INIT cannot fork child[%d] => suicide" , i );
     48            snprintf( string , 64 , "[INIT] cannot fork child[%d] => suicide" , i );
    4649            display_string( string );
    4750
     
    5861                // CHILD[i] display error message
    5962                snprintf( string , 64 ,
    60                 "CHILD[%d] cannot exec KSH[%d] / ret_exec = %d" , i , i , ret_exec );
     63                "[INIT ERROR] CHILD[%d] cannot exec KSH / ret_exec = %d" , i , ret_exec );
    6164                display_string( string );
    6265            }
     
    6568        {
    6669             // INIT display CHILD[i] process PID
    67              snprintf( string , 64 , "INIT created KSH[%d] / pid = %x", i , ret_fork );
     70             snprintf( string , 64 , "[INIT] created KSH[%d] / pid = %x", i , ret_fork );
    6871             display_string( string );
    6972
     
    7275        }
    7376    }
     77 
     78#if DEBUG_INIT
    7479
    75 // INIT display processes and threads in clusters 0 & 1
    76 display_cluster_processes( 0 );
    77 display_sched( 0 , 0 );
    78 display_cluster_processes( 1 );
    79 display_sched( 1 , 0 );
     80    unsigned int  x_size;        // number of clusters in a row
     81    unsigned int  y_size;        // number of clusters in a column
     82    unsigned int  ncores;        // number of cores per cluster
     83    unsigned int  x;             // cluster x coordinate
     84    unsigned int  y;             // cluster y coordinate
     85    unsigned int  cxy;           // cluster identifier
     86    unsigned int  lid;           // core local index
     87
     88    // get hardware config
     89    get_config( &x_size , &y_size , &ncores );
     90   
     91    // INIT displays processes and threads in all clusters
     92    for( x = 0 ; x < x_size ; x++ )
     93    {
     94        for( y = 0 ; y < y_size ; y++ )
     95        {
     96            cxy = CXY_FROM_XY( x , y );
     97            display_cluster_processes( cxy );
     98            for( lid = 0 ; lid < ncores ; lid++ )
     99            {
     100                display_sched( cxy , lid );
     101            }
     102        }
     103    }
     104
     105#endif
    80106
    81107    // This loop detects the termination of the KSH[i] processes,
     
    89115        {
    90116            // display string to report unexpected KSH process block
    91             snprintf( string , 64 , "KSH process %x stopped => unblock it" , rcv_pid );
     117            snprintf( string , 64 , "[INIT] KSH process %x stopped => unblock it" , rcv_pid );
    92118            display_string( string );
    93119
    94             // TODO : unblock KSH
     120            // TODO : unblock KSH [AG]
    95121
    96122        }  // end KSH stopped handling
     
    99125        {
    100126            // display string to report KSH process termination
    101             snprintf( string , 64 , "KSH process %x terminated => recreate KSH", rcv_pid );
     127            snprintf( string , 64 , "[INIT] KSH process %x terminated => recreate", rcv_pid );
    102128            display_string( string );
    103129
     
    108134            {
    109135                // INIT display error message
    110                 snprintf( string , 64 , "INIT cannot fork child => suicide");
     136                snprintf( string , 64 , "[INIT ERROR] cannot fork child => suicide");
    111137                display_string( string );
    112138
     
    122148                {
    123149                    // CHILD display error message on TXT0 terminal
    124                     snprintf( string , 64 , "CHILD cannot exec KSH" );
     150                    snprintf( string , 64 , "[INIT ERROR] CHILD cannot exec KSH" );
    125151                    display_string( string );
    126152                }
     
    129155            {
    130156                // INIT display new CHILD process PID
    131                 snprintf( string , 64 , "INIT forked CHILD / pid = %x", ret_fork );
     157                snprintf( string , 64 , "[INIT] forked CHILD / pid = %x", ret_fork );
    132158                display_string( string );
    133159            }
    134160        } // end KSH kill handling
    135161
    136 // INIT wait a fixed delay
    137 for( delay = 0 ; delay < 50000 ; delay++ ) asm volatile( "nop" );
     162#if( DEBUG_INIT )
    138163
    139 // INIT display processes and threads in clusters 0 & 1
    140 display_cluster_processes( 0 );
    141 display_sched( 0 , 0 );
    142 display_cluster_processes( 1 );
    143 display_sched( 1 , 0 );
     164        // INIT displays processes and threads in all clusters
     165        for( x = 0 ; x < x_size ; x++ )
     166        {
     167            for( y = 0 ; y < y_size ; y++ )
     168            {
     169                cxy = CXY_FROM_XY( x , y );
     170                display_cluster_processes( cxy );
     171                for( lid = 0 ; lid < ncores ; lid++ )
     172                {
     173                    display_sched( cxy , lid );
     174                }
     175            }
     176        }
     177
     178#endif
    144179
    145180    }  // end while waiting KSH[i] termination
  • trunk/user/ksh/Makefile

    r439 r440  
    2525
    2626clean:
    27         rm -rf build/*.o build/*.elf build/*.o.txt
     27        rm -rf build/*.o build/*.elf build/*.txt
    2828
    2929.PHONY: dirs clean
  • trunk/user/ksh/ksh.c

    r437 r440  
    380380    if( pid == 0 )
    381381    {
    382                 printf("  error: ilegal pid format\n" );
     382                printf("  error: kernel process 0 cannot be killed\n" );
    383383        }
    384384
    385385        if( kill( pid , SIGKILL ) )
    386386    {
    387                 printf("  error: unable to kill process %x\n", pid );
     387                printf("  error: process %x cannot be killed\n", pid );
    388388        }
    389389}   // end cmd_kill()
     
    421421    {
    422422        printf("  error: ksh process unable to fork\n");
     423        return;
    423424    }
    424425    else if (ret_fork == 0)      // it is the CHILD process
     
    433434        {
    434435            printf("  error: new process unable to exec <%s>\n", pathname );
    435             exit(0);
     436            return;
    436437        }   
    437438        }
     
    445446        if( rcv_pid == new_pid )
    446447        {
    447             printf("\n\n   exit %s / status = %x\n\n", pathname, (status &0xFF) );
     448            printf("\n\n   %s normal termination / status = %x\n\n",
     449            pathname , (status &0xFF) );
     450            return;
    448451        }
    449452        else
    450453        {
    451             printf("\n\n   abnormal termination for %s \n\n", pathname );
     454            printf("\n\n   %s abnormal termination / status = %x\n\n",
     455            pathname , (status &0xFF) );
     456            return;
    452457        }
    453458    }
    454                  
    455459}   // end cmd_load
    456460
     
    689693        ptr   = 0;
    690694
    691         printf( "~~~ shell ~~~\n\n" );
     695        printf( "\n\n~~~ shell ~~~\n\n" );
    692696
    693697        // command buffer initialisation
  • trunk/user/pgcd/Makefile

    r439 r440  
    44
    55-include ../../params-soft.mk
     6
    67ifeq ($(ARCH_NAME),)
    78$(error Please define in ARCH_NAME parameter in params-soft.mk!)
     
    1314
    1415compile: dirs build/pgcd.elf
     16
    1517build/pgcd.elf : $(OBJS) pgcd.ld
    1618        $(LD) -o $@ -T pgcd.ld $(OBJS) -nostdlib -L$(LIBC) -lc
     
    1921build/pgcd.o : pgcd.c
    2022        $(CC) $(INCLUDES) -L$(LIBC) $(CFLAGS) -c -o  $@ $<
    21         $(DU) -D $@ > $@.txt
    2223
    2324dirs:
     
    2526
    2627clean:
    27         rm -rf build/*.o build/*.elf build/*.o.txt
     28        rm -rf build/*.o  build/*.elf  build/*.txt
    2829
    2930.PHONY: dirs clean
  • trunk/user/sort/Makefile

    r439 r440  
    44
    55-include ../../params-soft.mk
     6
    67ifeq ($(ARCH_NAME),)
    78$(error Please define in ARCH_NAME parameter in params-soft.mk!)
     
    1314
    1415compile: dirs build/sort.elf
     16
    1517build/sort.elf : $(OBJS) sort.ld
    1618        $(LD) -o $@ -T sort.ld $(OBJS) -nostdlib -L$(LIBC) -L$(LIBPTHREAD) -lc -lpthread
     
    1921build/sort.o : sort.c
    2022        $(CC) $(INCLUDES) $(CFLAGS) -c -o  $@ $<
    21         $(DU) -D $@ > $@.txt
    2223
    2324dirs:
     
    2526
    2627clean:
    27         rm -rf build/*.o build/*.elf build/*.o.txt
     28        rm -rf build/*.o  build/*.elf  build/*.txt
    2829
    2930.PHONY: dirs clean
  • trunk/user/sort/sort.c

    r436 r440  
    2727#include <pthread.h>
    2828
    29 #define ARRAY_LENGTH    0x100    // 256 values
    30 #define VERBOSE         0
     29#define ARRAY_LENGTH        0x100    // 256 values
     30
     31#define MAX_THREADS         1024     // 16 * 16 * 4
     32
     33#define DISPLAY_ARRAY       0
     34#define DISPLAY_THREADS     1
    3135
    3236///////////////////////////////////////////////////////
    3337// macros for fixed format cxy <=> (x,y) translation
     38// TODO these macros are only for TSAR architecture...
    3439///////////////////////////////////////////////////////
    3540
     
    6166pthread_barrier_t   barrier;                 // synchronisation variables
    6267
     68pthread_attr_t      attr[MAX_THREADS];       // thread attributes (one per thread)
     69args_t              arg[MAX_THREADS];        // sort function arguments (one per thread)
    6370
    6471////////////////////////////////////
     
    135142    unsigned int       i;
    136143    unsigned long long cycle;
     144    unsigned int       cxy;
     145    unsigned int       lid;
    137146
    138147    int         * src_array  = NULL;
    139148    int         * dst_array  = NULL;
     149
     150    // get core coordinates an date
     151    get_core( &cxy , &lid );
     152    get_cycle( &cycle );
    140153
    141154    unsigned int  thread_uid = ptr->thread_uid;
     
    143156    unsigned int  main_uid   = ptr->main_uid;
    144157
     158printf("\n### core[%x,%d] enter sort : threads %d / thread_uid %x / main_uid %x / cycle %d\n",
     159cxy, lid, threads, thread_uid, main_uid, (int)cycle );
     160
     161    while( 1 ) { asm volatile("nop"); }
     162
    145163    unsigned int  items      = ARRAY_LENGTH / threads;
    146164    unsigned int  stages     = __builtin_ctz( threads ) + 1;
    147    
    148     get_cycle( &cycle );
    149     printf("\n[SORT] thread[%d] enter at cycle %d\n", thread_uid , (unsigned int)cycle );
    150 
    151     printf("\n[SORT] thread[%d] / stage 0 start\n", thread_uid );
    152165
    153166    bubbleSort( array0, items, items * thread_uid );
     
    157170    /////////////////////////////////
    158171    pthread_barrier_wait( &barrier );
     172
     173    printf("\n[SORT] thread[%d] exit barrier\n", thread_uid );
    159174
    160175    // the number of threads contributing to sort
     
    220235    pthread_t              trdid;              // kernel allocated thread index (unused)
    221236    pthread_barrierattr_t  barrier_attr;       // barrier attributes
    222     pthread_attr_t         attr[1024];         // thread attributes (one per thread)
    223     args_t                 arg[1024];          // sort function arguments (one per thread)
    224237
    225238    // compute number of threads (one thread per proc)
     
    251264
    252265    get_cycle( &cycle );
    253     printf("\n[SORT] starts : %d threads / %d values / cycle %d\n",
    254     threads, ARRAY_LENGTH , (unsigned int)cycle );
     266    printf("\n\n[SORT] main starts on core[%x,%d] / %d threads / %d values / cycle %d\n",
     267    main_cxy, main_lid, threads, ARRAY_LENGTH, (unsigned int)cycle );
    255268
    256269    // Barrier initialization
     
    265278
    266279    get_cycle( &cycle );
    267     printf("\n[SORT] completes barrier init at cycle %d\n", (unsigned int)cycle );
     280    printf("\n[SORT] main completes barrier init at cycle %d\n", (unsigned int)cycle );
    268281
    269282    // Array to sort initialization
     
    273286    }
    274287
    275 #if VERBOSE
     288#if DISPLAY_ARRAY
    276289printf("\n*** array before sort\n");
    277290for( n=0; n<ARRAY_LENGTH; n++) printf("array[%d] = %d\n", n , array0[n] );
     
    279292
    280293    get_cycle( &cycle );
    281     printf("\n[SORT] completes array init at cycle %d\n", (unsigned int)cycle );
     294    printf("\n[SORT] main completes array init at cycle %d\n", (unsigned int)cycle );
    282295
    283296    // launch other threads to execute sort() function
     
    303316                if( thread_uid != main_uid )
    304317                {
     318
     319get_cycle( &cycle );
     320printf("\n### main creates thread_uid %d / &sort_arg %x / cycle %d\n",
     321thread_uid, &arg[thread_uid], (unsigned int)cycle );
     322
    305323                    if ( pthread_create( &trdid,              // not used because no join
    306324                                         &attr[thread_uid],   // thread attributes
     
    308326                                         &arg[thread_uid] ) ) // sort arguments
    309327                    {
    310                         printf("\n[SORT ERROR] creating thread %x\n", thread_uid );
     328                        printf("\n[SORT ERROR] main created thread %x \n", thread_uid );
    311329                        exit( 0 );
    312330                    }
     331                }
    313332         
    314                 }
    315             }
    316         }
    317     }
    318 
    319     get_cycle( &cycle );
    320     printf("\n[SORT] completes threads create at cycle %d\n", (unsigned int)cycle );
    321 
    322    // main run also the sort() function
     333#if DISPLAY_THREADS
     334display_sched( CXY_FROM_XY(x,y) , lid );
     335#endif
     336            }
     337        }
     338    }
     339
     340    get_cycle( &cycle );
     341    printf("\n[SORT] main completes threads create at cycle %d\n", (unsigned int)cycle );
     342
     343    // main run also the sort() function
    323344    sort( &arg[main_uid] );
    324345
     
    335356        if ( res_array[n] > res_array[n+1] )
    336357        {
     358            printf("\n[SORT] array[%d] = %d > array[%d] = %d\n",
     359            n , res_array[n] , n+1 , res_array[n+1] );
    337360            success = 0;
    338361            break;
     
    340363    }
    341364
    342 #if VERBOSE
     365#if DISPLAY_ARRAY
    343366printf("\n*** array after sort\n");
    344367for( n=0; n<ARRAY_LENGTH; n++) printf("array[%d] = %d\n", n , res_array[n] );
Note: See TracChangeset for help on using the changeset viewer.