Main Page   File List  

atomic.h

Go to the documentation of this file.
00001 /* $Id: atomic.h 29248 2007-07-09 12:09:06Z aw11 $ */
00002 /*****************************************************************************/
00012 /* Copyright (C) 2000-2002
00013  * Dresden University of Technology, Operating Systems Research Group
00014  *
00015  * This file contains free software, you can redistribute it and/or modify
00016  * it under the terms of the GNU General Public License, Version 2 as
00017  * published by the Free Software Foundation (see the file COPYING).
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * For different licensing schemes please contact
00025  * <contact@os.inf.tu-dresden.de>.
00026  */
00027 /*****************************************************************************/
00028 #ifndef __L4UTIL__INCLUDE__ATOMIC_H__
00029 #define __L4UTIL__INCLUDE__ATOMIC_H__
00030 
00031 #include <l4/sys/l4int.h>
00032 #include <l4/sys/compiler.h>
00033 
00034 /*****************************************************************************
00035  *** Prototypes
00036  *****************************************************************************/
00037 
00038 EXTERN_C_BEGIN
00039 
00055 L4_INLINE int
00056 l4util_cmpxchg64(volatile l4_uint64_t * dest,
00057                  l4_uint64_t cmp_val, l4_uint64_t new_val);
00058 
00072 L4_INLINE int
00073 l4util_cmpxchg32(volatile l4_uint32_t * dest,
00074                  l4_uint32_t cmp_val, l4_uint32_t new_val);
00075 
00089 L4_INLINE int
00090 l4util_cmpxchg16(volatile l4_uint16_t * dest,
00091                  l4_uint16_t cmp_val, l4_uint16_t new_val);
00092 
00106 L4_INLINE int
00107 l4util_cmpxchg8(volatile l4_uint8_t * dest,
00108                 l4_uint8_t cmp_val, l4_uint8_t new_val);
00109 
00123 L4_INLINE int
00124 l4util_cmpxchg(volatile l4_umword_t * dest,
00125                l4_umword_t cmp_val, l4_umword_t new_val);
00126 
00136 L4_INLINE l4_uint32_t
00137 l4util_xchg32(volatile l4_uint32_t * dest, l4_uint32_t val);
00138 
00148 L4_INLINE l4_uint16_t
00149 l4util_xchg16(volatile l4_uint16_t * dest, l4_uint16_t val);
00150 
00160 L4_INLINE l4_uint8_t
00161 l4util_xchg8(volatile l4_uint8_t * dest, l4_uint8_t val);
00162 
00172 L4_INLINE l4_umword_t
00173 l4util_xchg(volatile l4_umword_t * dest, l4_umword_t val);
00174 
00176 
00184 L4_INLINE l4_uint8_t
00185 l4util_cmpxchg8_res(volatile l4_uint8_t *dest,
00186                     l4_uint8_t cmp_val, l4_uint8_t new_val);
00187 L4_INLINE l4_uint16_t
00188 l4util_cmpxchg16_res(volatile l4_uint16_t *dest,
00189                      l4_uint16_t cmp_val, l4_uint16_t new_val);
00190 L4_INLINE l4_uint32_t
00191 l4util_cmpxchg32_res(volatile l4_uint32_t *dest,
00192                      l4_uint32_t cmp_val, l4_uint32_t new_val);
00193 L4_INLINE l4_umword_t
00194 l4util_cmpxchg_res(volatile l4_umword_t *dest,
00195                    l4_umword_t cmp_val, l4_umword_t new_val);
00197 
00199 
00205 L4_INLINE void
00206 l4util_add8(volatile l4_uint8_t *dest, l4_uint8_t val);
00207 L4_INLINE void
00208 l4util_add16(volatile l4_uint16_t *dest, l4_uint16_t val);
00209 L4_INLINE void
00210 l4util_add32(volatile l4_uint32_t *dest, l4_uint32_t val);
00211 L4_INLINE void
00212 l4util_sub8(volatile l4_uint8_t *dest, l4_uint8_t val);
00213 L4_INLINE void
00214 l4util_sub16(volatile l4_uint16_t *dest, l4_uint16_t val);
00215 L4_INLINE void
00216 l4util_sub32(volatile l4_uint32_t *dest, l4_uint32_t val);
00217 L4_INLINE void
00218 l4util_and8(volatile l4_uint8_t *dest, l4_uint8_t val);
00219 L4_INLINE void
00220 l4util_and16(volatile l4_uint16_t *dest, l4_uint16_t val);
00221 L4_INLINE void
00222 l4util_and32(volatile l4_uint32_t *dest, l4_uint32_t val);
00223 L4_INLINE void
00224 l4util_or8(volatile l4_uint8_t *dest, l4_uint8_t val);
00225 L4_INLINE void
00226 l4util_or16(volatile l4_uint16_t *dest, l4_uint16_t val);
00227 L4_INLINE void
00228 l4util_or32(volatile l4_uint32_t *dest, l4_uint32_t val);
00230 
00232 
00239 L4_INLINE l4_uint8_t
00240 l4util_add8_res(volatile l4_uint8_t *dest, l4_uint8_t val);
00241 L4_INLINE l4_uint16_t
00242 l4util_add16_res(volatile l4_uint16_t *dest, l4_uint16_t val);
00243 L4_INLINE l4_uint32_t
00244 l4util_add32_res(volatile l4_uint32_t *dest, l4_uint32_t val);
00245 L4_INLINE l4_uint8_t
00246 l4util_sub8_res(volatile l4_uint8_t *dest, l4_uint8_t val);
00247 L4_INLINE l4_uint16_t
00248 l4util_sub16_res(volatile l4_uint16_t *dest, l4_uint16_t val);
00249 L4_INLINE l4_uint32_t
00250 l4util_sub32_res(volatile l4_uint32_t *dest, l4_uint32_t val);
00251 L4_INLINE l4_uint8_t
00252 l4util_and8_res(volatile l4_uint8_t *dest, l4_uint8_t val);
00253 L4_INLINE l4_uint16_t
00254 l4util_and16_res(volatile l4_uint16_t *dest, l4_uint16_t val);
00255 L4_INLINE l4_uint32_t
00256 l4util_and32_res(volatile l4_uint32_t *dest, l4_uint32_t val);
00257 L4_INLINE l4_uint8_t
00258 l4util_or8_res(volatile l4_uint8_t *dest, l4_uint8_t val);
00259 L4_INLINE l4_uint16_t
00260 l4util_or16_res(volatile l4_uint16_t *dest, l4_uint16_t val);
00261 L4_INLINE l4_uint32_t
00262 l4util_or32_res(volatile l4_uint32_t *dest, l4_uint32_t val);
00264 
00266 
00271 L4_INLINE void
00272 l4util_inc8(volatile l4_uint8_t *dest);
00273 L4_INLINE void
00274 l4util_inc16(volatile l4_uint16_t *dest);
00275 L4_INLINE void
00276 l4util_inc32(volatile l4_uint32_t *dest);
00277 L4_INLINE void
00278 l4util_dec8(volatile l4_uint8_t *dest);
00279 L4_INLINE void
00280 l4util_dec16(volatile l4_uint16_t *dest);
00281 L4_INLINE void
00282 l4util_dec32(volatile l4_uint32_t *dest);
00284 
00286 
00292 L4_INLINE l4_uint8_t
00293 l4util_inc8_res(volatile l4_uint8_t *dest);
00294 L4_INLINE l4_uint16_t
00295 l4util_inc16_res(volatile l4_uint16_t *dest);
00296 L4_INLINE l4_uint32_t
00297 l4util_inc32_res(volatile l4_uint32_t *dest);
00298 L4_INLINE l4_uint8_t
00299 l4util_dec8_res(volatile l4_uint8_t *dest);
00300 L4_INLINE l4_uint16_t
00301 l4util_dec16_res(volatile l4_uint16_t *dest);
00302 L4_INLINE l4_uint32_t
00303 l4util_dec32_res(volatile l4_uint32_t *dest);
00305 
00313 L4_INLINE void
00314 l4util_atomic_add(volatile long *dest, long val);
00315 
00322 L4_INLINE void
00323 l4util_atomic_inc(volatile long *dest);
00324 
00325 EXTERN_C_END
00326 
00327 /*****************************************************************************
00328  *** Get architecture specific implementations
00329  *****************************************************************************/
00330 #include <l4/util/atomic_arch.h>
00331 
00332 /*****************************************************************************
00333  *** Generic implementation
00334  ***    (make sure to prevent pagefaults between critical sections)
00335  ***  Do not use those functions, go implement a version for your
00336  ***  architecture!
00337  *****************************************************************************/
00338 
00339 #ifdef __GNUC__
00340 
00341 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_CMPXCHG16
00342 #include <l4/util/irq.h>
00343 
00344 L4_INLINE int
00345 l4util_cmpxchg16(volatile l4_uint16_t * dest,
00346                  l4_uint16_t cmp_val, l4_uint16_t new_val)
00347 {
00348   int ret = 0;
00349 
00350   l4util_cli();
00351 
00352   if (*dest == cmp_val)
00353     {
00354       *dest = new_val;
00355       ret = 1;
00356     }
00357 
00358   l4util_sti();
00359 
00360   return ret;
00361 }
00362 #endif
00363 
00364 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_CMPXCHG32
00365 #include <l4/util/irq.h>
00366 
00367 L4_INLINE int
00368 l4util_cmpxchg32(volatile l4_uint32_t * dest,
00369                  l4_uint32_t cmp_val, l4_uint32_t new_val)
00370 {
00371   int ret = 0;
00372 
00373   l4util_cli();
00374 
00375   if (*dest == cmp_val)
00376     {
00377       *dest = new_val;
00378       ret = 1;
00379     }
00380 
00381   l4util_sti();
00382 
00383   return ret;
00384 }
00385 #endif
00386 
00387 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_CMPXCHG
00388 #include <l4/util/irq.h>
00389 
00390 L4_INLINE int
00391 l4util_cmpxchg(volatile l4_umword_t * dest,
00392                l4_umword_t cmp_val, l4_umword_t new_val)
00393 {
00394   int ret = 0;
00395 
00396   l4util_cli();
00397 
00398   if (*dest == cmp_val)
00399     {
00400       *dest = new_val;
00401       ret = 1;
00402     }
00403 
00404   l4util_sti();
00405 
00406   return ret;
00407 }
00408 #endif
00409 
00410 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_CMPXCHG32_RES
00411 #include <l4/util/irq.h>
00412 
00413 L4_INLINE l4_uint32_t
00414 l4util_cmpxchg32_res(volatile l4_uint32_t * dest,
00415                      l4_uint32_t cmp_val, l4_uint32_t new_val)
00416 {
00417   l4_uint32_t old_val;
00418 
00419   l4util_cli();
00420 
00421   old_val = *dest;
00422 
00423   if (*dest == cmp_val)
00424     *dest = new_val;
00425 
00426   l4util_sti();
00427 
00428   return old_val;
00429 }
00430 #endif
00431 
00432 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_CMPXCHG_RES
00433 #include <l4/util/irq.h>
00434 
00435 L4_INLINE l4_umword_t
00436 l4util_cmpxchg_res(volatile l4_umword_t * dest,
00437                    l4_umword_t cmp_val, l4_umword_t new_val)
00438 {
00439   l4_umword_t old_val;
00440 
00441   l4util_cli();
00442 
00443   old_val = *dest;
00444 
00445   if (*dest == cmp_val)
00446     *dest = new_val;
00447 
00448   l4util_sti();
00449 
00450   return old_val;
00451 }
00452 #endif
00453 
00454 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_XCHG32
00455 #include <l4/util/irq.h>
00456 
00457 L4_INLINE l4_uint32_t
00458 l4util_xchg32(volatile l4_uint32_t * dest, l4_uint32_t val)
00459 {
00460   l4_uint32_t old_val;
00461 
00462   l4util_cli();
00463 
00464   old_val = *dest;
00465   *dest = val;
00466 
00467   l4util_sti();
00468 
00469   return old_val;
00470 }
00471 #endif
00472 
00473 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_XCHG
00474 #include <l4/util/irq.h>
00475 
00476 L4_INLINE l4_umword_t
00477 l4util_xchg(volatile l4_umword_t * dest, l4_umword_t val)
00478 {
00479   l4_umword_t old_val;
00480 
00481   l4util_cli();
00482 
00483   old_val = *dest;
00484   *dest = val;
00485 
00486   l4util_sti();
00487 
00488   return old_val;
00489 }
00490 #endif
00491 
00492 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_ADD
00493 #include <l4/util/irq.h>
00494 
00495 L4_INLINE void
00496 l4util_atomic_add(volatile long *dest, long val)
00497 {
00498   l4util_cli();
00499   *dest += val;
00500   l4util_sti();
00501 }
00502 #endif
00503 
00504 #ifndef __L4UTIL_ATOMIC_HAVE_ARCH_INC
00505 #include <l4/util/irq.h>
00506 
00507 L4_INLINE void
00508 l4util_atomic_inc(volatile long *dest)
00509 {
00510   l4util_cli();
00511   (*dest)++;
00512   l4util_sti();
00513 }
00514 #endif
00515 
00516 #endif //_GNUC__
00517 
00518 #endif /* ! __L4UTIL__INCLUDE__ATOMIC_H__ */

L4 Utilities, part of DROPS  © 2000-2003