Producing a simple multi-threaded CBE program

To produce a simple program for the CBE, you should follow the steps listed below (this example is included in the SDK in /opt/cell/sdk/src/tutorial/simple).

The project is called simple. For this example, the PPE code will be built in the project directory, instead of a ppu sub-directory.
  1. Create a directory named simple.
  2. In directory simple, create a file named Makefile using the following code:
    ########################################################################
    #			Subdirectories
    ########################################################################
    
    DIRS		:= 	spu
    
    ########################################################################
    #                       Target
    ########################################################################
    
    PROGRAM_ppu			:= 	simple
    
    ########################################################################
    #                       Local Defines
    ########################################################################
    
    IMPORTS         := spu/lib_simple_spu.a -lspe2 -lpthread
    # imports the embedded simple_spu library
    # allows consolidation of spu program into ppe binary
    
    ########################################################################
    #			make.footer
    ########################################################################
    
    # make.footer is in the top of the SDK
    ifdef CELL_TOP
    	include $(CELL_TOP)/buildutils/make.footer
    else
    	include ../../../../buildutils/make.footer
    endif
  3. In directory simple, create a file simple.c using the following code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <libspe2.h>
    #include <pthread.h>
    
    extern spe_program_handle_t simple_spu;
    
    #define MAX_SPU_THREADS 	16
    
    
    void *ppu_pthread_function(void *arg) {
    	spe_context_ptr_t ctx;
    	unsigned int entry = SPE_DEFAULT_ENTRY;
    	
    	ctx = *((spe_context_ptr_t *)arg);
    	if (spe_context_run(ctx,&entry, 0, NULL, NULL, NULL) < 0) {
    		perror ("Failed running context");
    		exit (1);
    	}
    	pthread_exit(NULL);
    }
    
    
    int main()
    {
    	int i,spu_threads;
    	spe_context_ptr_t ctxs[MAX_SPU_THREADS];
    	pthread_t threads[MAX_SPU_THREADS];
    
    /* Determine the number of SPE threads to create */
    spu_threads = spe_cpu_info_get(SPE_COUNT_USABLE_SPES, -1);
    if (spu_threads > MAX_SPU_THREADS) spu_threads = MAX_SPU_THREADS;
    
    	/* Create several SPE-threads to execute 'simple_spu' */
    	for(i=0; i<spu_threads; i++) {
    		/* Create context */
    		if ((ctxs[i] = spe_context_create (0, NULL)) == NULL) {
    			perror ("Failed creating context");
    			exit (1);
    		}
    		/* Load program into context */
    		if (spe_program_load (ctxs[i],&simple_spu)) {
    			perror ("Failed loading program");
    			exit (1);
    		}
    			/* Create thread for each SPE context */
        		if (pthread_create (&threads[i], NULL,&ppu_pthread_function,&ctxs[i]))  {
    			perror ("Failed creating thread");
    			exit (1);
      		}
    	
    	/* Wait for SPU-thread to complete execution. */
    	for (i=0; i<spu_threads; i++) {
    		if (pthread_join (threads[i], NULL)) {
    			perror("Failed pthread_join");
    			exit (1);
    		}
    	}
    	
    	printf("\nThe program has successfully executed.\n");
    	
    	return (0);
    } 
  4. Create a directory named spu.
  5. In the directory spu, create a file named Makefile using the following code:
    #######################################################################
    #			Target
    ########################################################################
    
    PROGRAMS_spu 			:= simple_spu
    
    # created embedded library
    LIBRARY_embed			:= lib_simple_spu.a
    
    ########################################################################
    #			make.footer
    ########################################################################
    
    # make.footer is in the top of the SDK
    ifdef CELL_TOP
    	include $(CELL_TOP)/buildutils/make.footer
    else
    	include ../../../../../buildutils/make.footer
    endif
  6. In the same directory, create a file simple_spu.c using the following code:
    #include <stdio.h>
    
    int main(unsigned long long id)
    {
    
    	/* The first parameter of an spu program will always be the spe_id of the spe
    	 * thread that issued it.
    	 */
    	printf("Hello Cell (0x%llx)\n", id);
    
    	return 0;
    }
  7. Compile the program by entering the following command at the command line while in the simple directory:
    make

This CBE program then creates SPE threads that output "Hello Cell (#)\n" to the systemsim output window, where # is the spe_id of the SPE thread that issued the print.