Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /***************************************************************************** 00002 * DESCRIPTION: 00003 * This example program illustrates the use of mutex variables 00004 * in a threads program. This version was obtained by modifying the 00005 * serial version of the program (dotprod_serial.c) which performs a 00006 * dot product. The main data is made available to all threads through 00007 * a globally accessible structure. Each thread works on a different 00008 * part of the data. The main thread waits for all the threads to complete 00009 * their computations, and then it prints the resulting sum. 00010 * SOURCE: Vijay Sonnad, IBM 00011 * MODIFICATOR: (Simon) CHENG Ye 00012 * LAST REVISED: 06/JAN/2013 00013 ******************************************************************************/ 00014 00015 #include "mbed.h" 00016 #include "cmsis_os.h" 00017 00018 Serial debug(USBTX, USBRX); 00019 00020 00021 /* 00022 * The following structure contains the necessary information 00023 * to allow the function "dotprod" to access its input data and 00024 * place its output into the structure. This structure is 00025 * unchanged from the sequential version. 00026 */ 00027 typedef struct 00028 { 00029 double *a; 00030 double *b; 00031 double sum; 00032 int veclen; 00033 } DOTDATA; 00034 00035 /* Define globally accessible variables and a mutex */ 00036 #define NUMTHRDS 4 00037 #define VECLEN 200 //Use a smaller size vector for limited memeory space on mbed 00038 DOTDATA dotstr; 00039 osMutexId stdio_mutex; 00040 osMutexDef(stdio_mutex); 00041 00042 /* 00043 * The function dotprod is activated when the thread is created. 00044 * As before, all input to this routine is obtained from a structure 00045 * of type DOTDATA and all output from this function is written into 00046 * this structure. The benefit of this approach is apparent for the 00047 * multi-threaded program: when a thread is created we pass a single 00048 * argument to the activated function - typically this argument 00049 * is a thread number. All the other information required by the 00050 * function is accessed from the globally accessible structure. 00051 */ 00052 void dotprod(void const *arg) 00053 { 00054 /* Define and use local variables for convenience */ 00055 osThreadId id; 00056 int i, start, end, len ; 00057 long offset; 00058 double mysum, *x, *y; 00059 offset = (long)arg; 00060 00061 len = dotstr.veclen; 00062 start = offset*len; 00063 end = start + len; 00064 x = dotstr.a; 00065 y = dotstr.b; 00066 00067 /* 00068 * Perform the dot product and assign result 00069 * to the appropriate variable in the structure. 00070 */ 00071 mysum = 0; 00072 for (i=start; i<end ; i++) 00073 mysum += (x[i] * y[i]); 00074 00075 /* 00076 * Lock a mutex prior to updating the value in the shared 00077 * structure, and unlock it upon updating. 00078 */ 00079 osMutexWait(stdio_mutex, osWaitForever); 00080 dotstr.sum += mysum; 00081 printf("Thread %ld did %d to %d: mysum=%f global sum=%f\n",offset,start,end,mysum,dotstr.sum); 00082 osMutexRelease(stdio_mutex); 00083 00084 id = osThreadGetId(); 00085 osThreadTerminate(id); 00086 } 00087 00088 void t0(void const *argument) {dotprod(argument);} 00089 osThreadDef(t0, osPriorityNormal, DEFAULT_STACK_SIZE); 00090 00091 void t1(void const *argument) {dotprod(argument);} 00092 osThreadDef(t1, osPriorityNormal, DEFAULT_STACK_SIZE); 00093 00094 void t2(void const *argument) {dotprod(argument);} 00095 osThreadDef(t2, osPriorityNormal, DEFAULT_STACK_SIZE); 00096 00097 void t3(void const *argument) {dotprod(argument);} 00098 osThreadDef(t3, osPriorityNormal, DEFAULT_STACK_SIZE); 00099 00100 /* 00101 * The main program creates threads which do all the work and then 00102 * print out result upon completion. Before creating the threads, 00103 * The input data is created. Since all threads update a shared structure, we 00104 * need a mutex for mutual exclusion. The main thread needs to wait for 00105 * all threads to complete, it waits for each one of the threads. We specify 00106 * a thread attribute value that allow the main thread to join with the 00107 * threads it creates. Note also that we free up handles when they are 00108 * no longer needed. 00109 */ 00110 int main() 00111 { 00112 debug.baud(57600); 00113 00114 long i; 00115 double *a, *b; 00116 00117 /* Assign storage and initialize values */ 00118 a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 00119 b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 00120 00121 for (i=0; i<VECLEN*NUMTHRDS; i++) 00122 { 00123 a[i]=1; 00124 b[i]=a[i]; 00125 } 00126 00127 dotstr.veclen = VECLEN; 00128 dotstr.a = a; 00129 dotstr.b = b; 00130 dotstr.sum=0; 00131 00132 stdio_mutex = osMutexCreate(osMutex(stdio_mutex)); 00133 00134 /* Create threads to perform the dotproduct */ 00135 for(i=0;i<NUMTHRDS;i++) 00136 { 00137 /* Each thread works on a different set of data. 00138 * The offset is specified by 'i'. The size of 00139 * the data for each thread is indicated by VECLEN. 00140 */ 00141 if(i==0) osThreadCreate(osThread(t0), (void *)i); 00142 if(i==1) osThreadCreate(osThread(t1), (void *)i); 00143 if(i==2) osThreadCreate(osThread(t2), (void *)i); 00144 if(i==3) osThreadCreate(osThread(t3), (void *)i); 00145 } 00146 00147 printf ("Sum = %f \n", dotstr.sum); 00148 free (a); 00149 free (b); 00150 } 00151 00152
Generated on Wed Jul 13 2022 03:48:01 by
1.7.2