cmsis rtos demo: mutex

Dependencies:   mbed-rtos mbed

Committer:
cnhzcy14
Date:
Sun Jan 06 15:03:44 2013 +0000
Revision:
1:1308d7d6d53e
Parent:
0:fba50ae123e6
comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cnhzcy14 1:1308d7d6d53e 1 /*****************************************************************************
cnhzcy14 1:1308d7d6d53e 2 * DESCRIPTION:
cnhzcy14 1:1308d7d6d53e 3 * This example program illustrates the use of mutex variables
cnhzcy14 1:1308d7d6d53e 4 * in a threads program. This version was obtained by modifying the
cnhzcy14 1:1308d7d6d53e 5 * serial version of the program (dotprod_serial.c) which performs a
cnhzcy14 1:1308d7d6d53e 6 * dot product. The main data is made available to all threads through
cnhzcy14 1:1308d7d6d53e 7 * a globally accessible structure. Each thread works on a different
cnhzcy14 1:1308d7d6d53e 8 * part of the data. The main thread waits for all the threads to complete
cnhzcy14 1:1308d7d6d53e 9 * their computations, and then it prints the resulting sum.
cnhzcy14 1:1308d7d6d53e 10 * SOURCE: Vijay Sonnad, IBM
cnhzcy14 1:1308d7d6d53e 11 * MODIFICATOR: (Simon) CHENG Ye
cnhzcy14 1:1308d7d6d53e 12 * LAST REVISED: 06/JAN/2013
cnhzcy14 1:1308d7d6d53e 13 ******************************************************************************/
cnhzcy14 1:1308d7d6d53e 14
cnhzcy14 0:fba50ae123e6 15 #include "mbed.h"
cnhzcy14 0:fba50ae123e6 16 #include "cmsis_os.h"
cnhzcy14 0:fba50ae123e6 17
cnhzcy14 0:fba50ae123e6 18 Serial debug(USBTX, USBRX);
cnhzcy14 0:fba50ae123e6 19
cnhzcy14 1:1308d7d6d53e 20
cnhzcy14 1:1308d7d6d53e 21 /*
cnhzcy14 1:1308d7d6d53e 22 * The following structure contains the necessary information
cnhzcy14 1:1308d7d6d53e 23 * to allow the function "dotprod" to access its input data and
cnhzcy14 1:1308d7d6d53e 24 * place its output into the structure. This structure is
cnhzcy14 1:1308d7d6d53e 25 * unchanged from the sequential version.
cnhzcy14 1:1308d7d6d53e 26 */
cnhzcy14 0:fba50ae123e6 27 typedef struct
cnhzcy14 0:fba50ae123e6 28 {
cnhzcy14 0:fba50ae123e6 29 double *a;
cnhzcy14 0:fba50ae123e6 30 double *b;
cnhzcy14 0:fba50ae123e6 31 double sum;
cnhzcy14 0:fba50ae123e6 32 int veclen;
cnhzcy14 0:fba50ae123e6 33 } DOTDATA;
cnhzcy14 0:fba50ae123e6 34
cnhzcy14 1:1308d7d6d53e 35 /* Define globally accessible variables and a mutex */
cnhzcy14 0:fba50ae123e6 36 #define NUMTHRDS 4
cnhzcy14 1:1308d7d6d53e 37 #define VECLEN 200 //Use a smaller size vector for limited memeory space on mbed
cnhzcy14 0:fba50ae123e6 38 DOTDATA dotstr;
cnhzcy14 0:fba50ae123e6 39 osMutexId stdio_mutex;
cnhzcy14 0:fba50ae123e6 40 osMutexDef(stdio_mutex);
cnhzcy14 0:fba50ae123e6 41
cnhzcy14 1:1308d7d6d53e 42 /*
cnhzcy14 1:1308d7d6d53e 43 * The function dotprod is activated when the thread is created.
cnhzcy14 1:1308d7d6d53e 44 * As before, all input to this routine is obtained from a structure
cnhzcy14 1:1308d7d6d53e 45 * of type DOTDATA and all output from this function is written into
cnhzcy14 1:1308d7d6d53e 46 * this structure. The benefit of this approach is apparent for the
cnhzcy14 1:1308d7d6d53e 47 * multi-threaded program: when a thread is created we pass a single
cnhzcy14 1:1308d7d6d53e 48 * argument to the activated function - typically this argument
cnhzcy14 1:1308d7d6d53e 49 * is a thread number. All the other information required by the
cnhzcy14 1:1308d7d6d53e 50 * function is accessed from the globally accessible structure.
cnhzcy14 1:1308d7d6d53e 51 */
cnhzcy14 0:fba50ae123e6 52 void dotprod(void const *arg)
cnhzcy14 0:fba50ae123e6 53 {
cnhzcy14 1:1308d7d6d53e 54 /* Define and use local variables for convenience */
cnhzcy14 0:fba50ae123e6 55 osThreadId id;
cnhzcy14 0:fba50ae123e6 56 int i, start, end, len ;
cnhzcy14 0:fba50ae123e6 57 long offset;
cnhzcy14 0:fba50ae123e6 58 double mysum, *x, *y;
cnhzcy14 0:fba50ae123e6 59 offset = (long)arg;
cnhzcy14 0:fba50ae123e6 60
cnhzcy14 0:fba50ae123e6 61 len = dotstr.veclen;
cnhzcy14 0:fba50ae123e6 62 start = offset*len;
cnhzcy14 0:fba50ae123e6 63 end = start + len;
cnhzcy14 0:fba50ae123e6 64 x = dotstr.a;
cnhzcy14 0:fba50ae123e6 65 y = dotstr.b;
cnhzcy14 0:fba50ae123e6 66
cnhzcy14 1:1308d7d6d53e 67 /*
cnhzcy14 1:1308d7d6d53e 68 * Perform the dot product and assign result
cnhzcy14 1:1308d7d6d53e 69 * to the appropriate variable in the structure.
cnhzcy14 1:1308d7d6d53e 70 */
cnhzcy14 0:fba50ae123e6 71 mysum = 0;
cnhzcy14 0:fba50ae123e6 72 for (i=start; i<end ; i++)
cnhzcy14 0:fba50ae123e6 73 mysum += (x[i] * y[i]);
cnhzcy14 0:fba50ae123e6 74
cnhzcy14 1:1308d7d6d53e 75 /*
cnhzcy14 1:1308d7d6d53e 76 * Lock a mutex prior to updating the value in the shared
cnhzcy14 1:1308d7d6d53e 77 * structure, and unlock it upon updating.
cnhzcy14 1:1308d7d6d53e 78 */
cnhzcy14 0:fba50ae123e6 79 osMutexWait(stdio_mutex, osWaitForever);
cnhzcy14 0:fba50ae123e6 80 dotstr.sum += mysum;
cnhzcy14 0:fba50ae123e6 81 printf("Thread %ld did %d to %d: mysum=%f global sum=%f\n",offset,start,end,mysum,dotstr.sum);
cnhzcy14 0:fba50ae123e6 82 osMutexRelease(stdio_mutex);
cnhzcy14 0:fba50ae123e6 83
cnhzcy14 0:fba50ae123e6 84 id = osThreadGetId();
cnhzcy14 0:fba50ae123e6 85 osThreadTerminate(id);
cnhzcy14 0:fba50ae123e6 86 }
cnhzcy14 0:fba50ae123e6 87
cnhzcy14 0:fba50ae123e6 88 void t0(void const *argument) {dotprod(argument);}
cnhzcy14 0:fba50ae123e6 89 osThreadDef(t0, osPriorityNormal, DEFAULT_STACK_SIZE);
cnhzcy14 0:fba50ae123e6 90
cnhzcy14 0:fba50ae123e6 91 void t1(void const *argument) {dotprod(argument);}
cnhzcy14 0:fba50ae123e6 92 osThreadDef(t1, osPriorityNormal, DEFAULT_STACK_SIZE);
cnhzcy14 0:fba50ae123e6 93
cnhzcy14 0:fba50ae123e6 94 void t2(void const *argument) {dotprod(argument);}
cnhzcy14 0:fba50ae123e6 95 osThreadDef(t2, osPriorityNormal, DEFAULT_STACK_SIZE);
cnhzcy14 0:fba50ae123e6 96
cnhzcy14 0:fba50ae123e6 97 void t3(void const *argument) {dotprod(argument);}
cnhzcy14 0:fba50ae123e6 98 osThreadDef(t3, osPriorityNormal, DEFAULT_STACK_SIZE);
cnhzcy14 0:fba50ae123e6 99
cnhzcy14 1:1308d7d6d53e 100 /*
cnhzcy14 1:1308d7d6d53e 101 * The main program creates threads which do all the work and then
cnhzcy14 1:1308d7d6d53e 102 * print out result upon completion. Before creating the threads,
cnhzcy14 1:1308d7d6d53e 103 * The input data is created. Since all threads update a shared structure, we
cnhzcy14 1:1308d7d6d53e 104 * need a mutex for mutual exclusion. The main thread needs to wait for
cnhzcy14 1:1308d7d6d53e 105 * all threads to complete, it waits for each one of the threads. We specify
cnhzcy14 1:1308d7d6d53e 106 * a thread attribute value that allow the main thread to join with the
cnhzcy14 1:1308d7d6d53e 107 * threads it creates. Note also that we free up handles when they are
cnhzcy14 1:1308d7d6d53e 108 * no longer needed.
cnhzcy14 1:1308d7d6d53e 109 */
cnhzcy14 1:1308d7d6d53e 110 int main()
cnhzcy14 1:1308d7d6d53e 111 {
cnhzcy14 0:fba50ae123e6 112 debug.baud(57600);
cnhzcy14 0:fba50ae123e6 113
cnhzcy14 0:fba50ae123e6 114 long i;
cnhzcy14 0:fba50ae123e6 115 double *a, *b;
cnhzcy14 0:fba50ae123e6 116
cnhzcy14 0:fba50ae123e6 117 /* Assign storage and initialize values */
cnhzcy14 0:fba50ae123e6 118 a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
cnhzcy14 0:fba50ae123e6 119 b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
cnhzcy14 0:fba50ae123e6 120
cnhzcy14 1:1308d7d6d53e 121 for (i=0; i<VECLEN*NUMTHRDS; i++)
cnhzcy14 1:1308d7d6d53e 122 {
cnhzcy14 1:1308d7d6d53e 123 a[i]=1;
cnhzcy14 1:1308d7d6d53e 124 b[i]=a[i];
cnhzcy14 1:1308d7d6d53e 125 }
cnhzcy14 0:fba50ae123e6 126
cnhzcy14 0:fba50ae123e6 127 dotstr.veclen = VECLEN;
cnhzcy14 0:fba50ae123e6 128 dotstr.a = a;
cnhzcy14 0:fba50ae123e6 129 dotstr.b = b;
cnhzcy14 0:fba50ae123e6 130 dotstr.sum=0;
cnhzcy14 0:fba50ae123e6 131
cnhzcy14 0:fba50ae123e6 132 stdio_mutex = osMutexCreate(osMutex(stdio_mutex));
cnhzcy14 0:fba50ae123e6 133
cnhzcy14 1:1308d7d6d53e 134 /* Create threads to perform the dotproduct */
cnhzcy14 0:fba50ae123e6 135 for(i=0;i<NUMTHRDS;i++)
cnhzcy14 0:fba50ae123e6 136 {
cnhzcy14 1:1308d7d6d53e 137 /* Each thread works on a different set of data.
cnhzcy14 1:1308d7d6d53e 138 * The offset is specified by 'i'. The size of
cnhzcy14 1:1308d7d6d53e 139 * the data for each thread is indicated by VECLEN.
cnhzcy14 1:1308d7d6d53e 140 */
cnhzcy14 0:fba50ae123e6 141 if(i==0) osThreadCreate(osThread(t0), (void *)i);
cnhzcy14 0:fba50ae123e6 142 if(i==1) osThreadCreate(osThread(t1), (void *)i);
cnhzcy14 0:fba50ae123e6 143 if(i==2) osThreadCreate(osThread(t2), (void *)i);
cnhzcy14 0:fba50ae123e6 144 if(i==3) osThreadCreate(osThread(t3), (void *)i);
cnhzcy14 0:fba50ae123e6 145 }
cnhzcy14 0:fba50ae123e6 146
cnhzcy14 0:fba50ae123e6 147 printf ("Sum = %f \n", dotstr.sum);
cnhzcy14 0:fba50ae123e6 148 free (a);
cnhzcy14 0:fba50ae123e6 149 free (b);
cnhzcy14 0:fba50ae123e6 150 }
cnhzcy14 0:fba50ae123e6 151
cnhzcy14 0:fba50ae123e6 152