This example requires POSIX thread (pthread) libraries and, therefore, runs only on
UNIX® platforms. It is a simple multithreaded example that uses
no persistent or global data. Two threads call the
MATLAB® function matrix_exp
with different sets of input
data.
To call the reentrant code, provide a main
function
that:
Includes the header file matrix_exp.h
.
For each thread, allocates memory for stack data.
Calls the matrix_exp_initialize
housekeeping
function. For more information, see Deploy Generated Code.
Calls matrix_exp
.
Calls matrix_exp_terminate
.
Frees the memory used for stack data.
For this example, main.c
contains:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include "matrix_exp.h" #include "matrix_exp_initialize.h" #include "matrix_exp_terminate.h" #include "rtwtypes.h" #define NUMELEMENTS (160*160) typedef struct { real_T in[NUMELEMENTS]; real_T out[NUMELEMENTS]; matrix_expStackData* spillData; } IODATA; /* The thread_function calls the matrix_exp function written in MATLAB */ void *thread_function(void *dummyPtr) { IODATA *myIOData = (IODATA*)dummyPtr; matrix_exp_initialize(); matrix_exp(myIOData->spillData, myIOData->in, myIOData->out); matrix_exp_terminate(); } int main() { pthread_t thread1, thread2; int iret1, iret2; IODATA data1; IODATA data2; int32_T i; /*Initializing data for passing to the 2 threads*/ matrix_expStackData* sd1=(matrix_expStackData*)calloc(1,sizeof(matrix_expStackData)); matrix_expStackData* sd2=(matrix_expStackData*)calloc(1,sizeof(matrix_expStackData)); data1.spillData = sd1; data2.spillData = sd2; for (i=0;i<NUMELEMENTS;i++) { data1.in[i] = 1; data1.out[i] = 0; data2.in[i] = 1.1; data2.out[i] = 0; } /*Initializing the 2 threads and passing required data to the thread functions*/ printf("Starting thread 1...\n"); iret1 = pthread_create(&thread1, NULL, thread_function, (void*) &data1); if (iret1 != 0){ perror( "Thread 1 creation failed."); exit(EXIT_FAILURE); } printf("Starting thread 2...\n"); iret2 = pthread_create(&thread2, NULL, thread_function, (void*) &data2); if (iret2 != 0){ perror( "Thread 2 creation failed."); exit(EXIT_FAILURE); } /*Wait for both the threads to finish execution*/ iret1 = pthread_join(thread1, NULL); if (iret1 != 0){ perror( "Thread 1 join failed."); exit(EXIT_FAILURE); } iret2 = pthread_join(thread2, NULL); if (iret2 != 0){ perror( "Thread 2 join failed."); exit(EXIT_FAILURE); } free(sd1); free(sd2); printf("Finished Execution!\n"); exit(EXIT_SUCCESS); } |
To generate code, run the following script at the MATLAB command prompt.
% This example can only be run on Unix platforms if ~isunix error('This example requires pthread libraries and can only be run on Unix.'); end % Setting the options for the Config object % Create a code gen configuration object cfg = coder.config('exe'); % Enable reentrant code generation cfg.MultiInstanceCode = true; % Set the post code generation command to be the 'setbuildargs' function cfg.PostCodeGenCommand = 'setbuildargs(buildInfo)'; % Compiling codegen -config cfg main.c matrix_exp.m -report -args ones(160,160) |
This script:
Generates an error message if the example is not running on a UNIX platform.
Creates a code configuration object for generation of an executable.
Enables the MultiInstanceCode
option
to generate reusable, reentrant code.
Uses the PostCodeGenCommand
option
to set the post code generation command to be the setbuildargs
function.
This function sets the -lpthread
flag to specify
that the build include the pthread library.
function setbuildargs(buildInfo) % The example being compiled requires pthread support. % The -lpthread flag requests that the pthread library % be included in the build linkFlags = {'-lpthread'}; addLinkFlags(buildInfo, linkFlags);
For more information, see Build Process Customization.
Invokes codegen
with the following
options:
-config
to pass in the code generation
configuration object cfg
.
main.c
to include this file in
the compilation.
-report
to create a code generation
report.
-args
to specify an example input
with class, size, and complexity.
codegen
generates a header file matrix_exp_types.h
,
which defines the matrix_expStackData
global structure.
This structure contains local variables that are too large to fit
on the stack.
/* * matrix_exp_types.h * * Code generation for function 'matrix_exp' * */ #ifndef __MATRIX_EXP_TYPES_H__ #define __MATRIX_EXP_TYPES_H__ /* Include files */ #include "rtwtypes.h" /* Type Definitions */ #ifndef typedef_matrix_expStackData #define typedef_matrix_expStackData typedef struct { struct { double F[25600]; double Y[25600]; double X[25600]; } f0; } matrix_expStackData; #endif /*typedef_matrix_expStackData*/ #endif /* End of code generation (matrix_exp_types.h) */ |
Call the code using the command:
system('./matrix_exp')