| /**************************************************************************** |
| * apps/examples/nxflat/tests/mutex/mutex.c |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <stdbool.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <pthread.h> |
| |
| /**************************************************************************** |
| * Private Data |
| ****************************************************************************/ |
| |
| static pthread_mutex_t mut; |
| static volatile int my_mutex = 0; |
| static unsigned long nloops[2] = {0, 0}; |
| static unsigned long nerrors[2] = {0, 0}; |
| static volatile bool bendoftest; |
| |
| /**************************************************************************** |
| * Private Functions |
| ****************************************************************************/ |
| |
| /* NOTE: it is necessary for functions that are referred to by function pointers |
| * pointer to be declared with global scope (at least for ARM). Otherwise, |
| * a relocation type that is not supported by NXFLAT is generated by GCC. |
| */ |
| |
| void thread_func(void *parameter) |
| { |
| int my_id = (int)parameter; |
| int my_ndx = my_id - 1; |
| int i; |
| |
| /* Loop 20 times. There is a 100 MS delay in the loop so this should |
| * take about 2 seconds. The main thread will stop this thread after |
| * 2 seconds by setting bendoftest in any event. |
| */ |
| |
| for (i = 0; i < 20 && !bendoftest; i++) |
| { |
| if ((pthread_mutex_lock(&mut)) != 0) |
| { |
| printf("ERROR thread %d: pthread_mutex_lock failed\n", my_id); |
| } |
| |
| if (my_mutex == 1) |
| { |
| printf("ERROR thread=%d: " |
| "my_mutex should be zero, instead my_mutex=%d\n", |
| my_id, my_mutex); |
| nerrors[my_ndx]++; |
| } |
| |
| my_mutex = 1; |
| usleep(100000); |
| my_mutex = 0; |
| |
| if ((pthread_mutex_unlock(&mut)) != 0) |
| { |
| printf("ERROR thread %d: pthread_mutex_unlock failed\n", my_id); |
| } |
| |
| nloops[my_ndx]++; |
| } |
| } |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| int main(int argc, char **argv) |
| { |
| pthread_t thread1; |
| pthread_t thread2; |
| |
| /* Initialize the mutex */ |
| |
| pthread_mutex_init(&mut, NULL); |
| |
| /* Start two thread instances */ |
| |
| printf("Starting thread 1\n"); |
| bendoftest = false; |
| if ((pthread_create(&thread1, NULL, (void*)thread_func, (void *)1)) != 0) |
| { |
| fprintf(stderr, "Error in thread#1 creation\n"); |
| } |
| |
| printf("Starting thread 2\n"); |
| if ((pthread_create(&thread2, NULL, (void*)thread_func, (void*)2)) != 0) |
| { |
| fprintf(stderr, "Error in thread#2 creation\n"); |
| } |
| |
| /* Wait a bit for the threads to do their thing. */ |
| |
| sleep(2); |
| |
| /* Then ask them politely to stop running */ |
| |
| printf("Stopping threads\n"); |
| bendoftest = true; |
| pthread_join(thread1, NULL); |
| pthread_join(thread2, NULL); |
| |
| printf("\tThread1\tThread2\n"); |
| printf("Loops\t%lu\t%lu\n", nloops[0], nloops[1]); |
| printf("Errors\t%lu\t%lu\n", nerrors[0], nerrors[1]); |
| |
| return 0; |
| } |