rtapi_mutex.h
1 #ifndef RTAPI_MUTEX_H 2 #define RTAPI_MUTEX_H 3 4 // Copyright 2004-2015 Jeff Epler, John Kasunich, Paul Corner, and other 5 // authors 6 // 7 // This program is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License as published by 9 // the Free Software Foundation; either version 2 of the License, or 10 // (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 21 /*********************************************************************** 22 * LIGHTWEIGHT MUTEX FUNCTIONS * 23 ************************************************************************/ 24 #if defined(__KERNEL__) 25 #include <linux/sched.h> /* for blocking when needed */ 26 #else 27 #include <sched.h> /* for blocking when needed */ 28 #endif 29 #include "rtapi_bitops.h" /* atomic bit ops for lightweight mutex */ 30 31 typedef unsigned long rtapi_mutex_t; 32 33 /** These three functions provide a very simple way to do mutual 34 exclusion around shared resources. They do _not_ replace 35 semaphores, and can result in significant slowdowns if contention 36 is severe. However, unlike semaphores they can be used from both 37 user and kernel space. The 'try' and 'give' functions are non- 38 blocking, and can be used anywhere. The 'get' function blocks if 39 the mutex is already taken, and can only be used in user space or 40 the init code of a realtime module, _not_ in realtime code. 41 */ 42 43 /** 'rtapi_mutex_give()' releases the mutex pointed to by 'mutex'. 44 The release is unconditional, even if the caller doesn't have 45 the mutex, it will be released. 46 */ 47 static __inline__ void rtapi_mutex_give(unsigned long *mutex) { 48 test_and_clear_bit(0, mutex); 49 } 50 /** 'rtapi_mutex_try()' makes a non-blocking attempt to get the 51 mutex pointed to by 'mutex'. If the mutex was available, it 52 returns 0 and the mutex is no longer available, since the 53 caller now has it. If the mutex is not available, it returns 54 a non-zero value to indicate that someone else has the mutex. 55 The programer is responsible for "doing the right thing" when 56 it returns non-zero. "Doing the right thing" almost certainly 57 means doing something that will yield the CPU, so that whatever 58 other process has the mutex gets a chance to release it. 59 */ static __inline__ int rtapi_mutex_try(unsigned long *mutex) { 60 return test_and_set_bit(0, mutex); 61 } 62 63 /** 'rtapi_mutex_get()' gets the mutex pointed to by 'mutex', 64 blocking if the mutex is not available. Because of this, 65 calling it from a realtime task is a "very bad" thing to 66 do. 67 */ 68 static __inline__ void rtapi_mutex_get(unsigned long *mutex) { 69 while (test_and_set_bit(0, mutex)) { 70 #if defined(__KERNEL__) 71 schedule(); 72 #else 73 sched_yield(); 74 #endif 75 } 76 } 77 78 79 #endif