Ye Cheng
/
cmsis_rtos_demo_mutex
cmsis rtos demo: mutex
Revision 1:1308d7d6d53e, committed 2013-01-06
- Comitter:
- cnhzcy14
- Date:
- Sun Jan 06 15:03:44 2013 +0000
- Parent:
- 0:fba50ae123e6
- Commit message:
- comments
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r fba50ae123e6 -r 1308d7d6d53e main.cpp --- a/main.cpp Sun Jan 06 14:20:05 2013 +0000 +++ b/main.cpp Sun Jan 06 15:03:44 2013 +0000 @@ -1,8 +1,29 @@ +/***************************************************************************** + * DESCRIPTION: + * This example program illustrates the use of mutex variables + * in a threads program. This version was obtained by modifying the + * serial version of the program (dotprod_serial.c) which performs a + * dot product. The main data is made available to all threads through + * a globally accessible structure. Each thread works on a different + * part of the data. The main thread waits for all the threads to complete + * their computations, and then it prints the resulting sum. + * SOURCE: Vijay Sonnad, IBM + * MODIFICATOR: (Simon) CHENG Ye + * LAST REVISED: 06/JAN/2013 + ******************************************************************************/ + #include "mbed.h" #include "cmsis_os.h" Serial debug(USBTX, USBRX); + +/* + * The following structure contains the necessary information + * to allow the function "dotprod" to access its input data and + * place its output into the structure. This structure is + * unchanged from the sequential version. + */ typedef struct { double *a; @@ -11,16 +32,26 @@ int veclen; } DOTDATA; +/* Define globally accessible variables and a mutex */ #define NUMTHRDS 4 -#define VECLEN 200 +#define VECLEN 200 //Use a smaller size vector for limited memeory space on mbed DOTDATA dotstr; osMutexId stdio_mutex; osMutexDef(stdio_mutex); - - +/* + * The function dotprod is activated when the thread is created. + * As before, all input to this routine is obtained from a structure + * of type DOTDATA and all output from this function is written into + * this structure. The benefit of this approach is apparent for the + * multi-threaded program: when a thread is created we pass a single + * argument to the activated function - typically this argument + * is a thread number. All the other information required by the + * function is accessed from the globally accessible structure. + */ void dotprod(void const *arg) { + /* Define and use local variables for convenience */ osThreadId id; int i, start, end, len ; long offset; @@ -33,12 +64,18 @@ x = dotstr.a; y = dotstr.b; + /* + * Perform the dot product and assign result + * to the appropriate variable in the structure. + */ mysum = 0; for (i=start; i<end ; i++) - { mysum += (x[i] * y[i]); - } + /* + * Lock a mutex prior to updating the value in the shared + * structure, and unlock it upon updating. + */ osMutexWait(stdio_mutex, osWaitForever); dotstr.sum += mysum; printf("Thread %ld did %d to %d: mysum=%f global sum=%f\n",offset,start,end,mysum,dotstr.sum); @@ -48,7 +85,6 @@ osThreadTerminate(id); } - void t0(void const *argument) {dotprod(argument);} osThreadDef(t0, osPriorityNormal, DEFAULT_STACK_SIZE); @@ -61,22 +97,32 @@ void t3(void const *argument) {dotprod(argument);} osThreadDef(t3, osPriorityNormal, DEFAULT_STACK_SIZE); -int main() { +/* + * The main program creates threads which do all the work and then + * print out result upon completion. Before creating the threads, + * The input data is created. Since all threads update a shared structure, we + * need a mutex for mutual exclusion. The main thread needs to wait for + * all threads to complete, it waits for each one of the threads. We specify + * a thread attribute value that allow the main thread to join with the + * threads it creates. Note also that we free up handles when they are + * no longer needed. + */ +int main() +{ debug.baud(57600); long i; double *a, *b; - //void *status; /* Assign storage and initialize values */ - a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); - for (i=0; i<VECLEN*NUMTHRDS; i++) { - a[i]=1; - b[i]=a[i]; - } + for (i=0; i<VECLEN*NUMTHRDS; i++) + { + a[i]=1; + b[i]=a[i]; + } dotstr.veclen = VECLEN; dotstr.a = a; @@ -85,8 +131,13 @@ stdio_mutex = osMutexCreate(osMutex(stdio_mutex)); + /* Create threads to perform the dotproduct */ for(i=0;i<NUMTHRDS;i++) { + /* Each thread works on a different set of data. + * The offset is specified by 'i'. The size of + * the data for each thread is indicated by VECLEN. + */ if(i==0) osThreadCreate(osThread(t0), (void *)i); if(i==1) osThreadCreate(osThread(t1), (void *)i); if(i==2) osThreadCreate(osThread(t2), (void *)i);