lib.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //! Symbols and externs that `ralloc` depends on.
  2. //!
  3. //! This crate provides implementation/import of these in Linux, BSD, and Mac OS.
  4. #![feature(lang_items, linkage)]
  5. #![no_std]
  6. #![warn(missing_docs)]
  7. extern crate libc;
  8. pub use libc::sched_yield;
  9. extern {
  10. /// Change the data segment. See `man sbrk`.
  11. pub fn sbrk(libc::intptr_t) -> *const libc::c_void;
  12. }
  13. /// Thread destructors for Linux.
  14. #[cfg(target_os = "linux")]
  15. pub mod thread_destructor {
  16. use libc;
  17. extern {
  18. #[linkage = "extern_weak"]
  19. static __dso_handle: *mut u8;
  20. #[linkage = "extern_weak"]
  21. static __cxa_thread_atexit_impl: *const libc::c_void;
  22. }
  23. /// Does this platform support thread destructors?
  24. ///
  25. /// This will return true, if and only if `__cxa_thread_atexit_impl` is non-null.
  26. #[inline]
  27. pub fn is_supported() -> bool {
  28. !__cxa_thread_atexit_impl.is_null()
  29. }
  30. /// Register a thread destructor.
  31. ///
  32. /// # Safety
  33. ///
  34. /// This is unsafe due to accepting (and dereferencing) raw pointers, as well as running an
  35. /// arbitrary unsafe function.
  36. ///
  37. /// On older system without the `__cxa_thread_atexit_impl` symbol, this is unsafe to call, and will
  38. /// likely segfault.
  39. // TODO: Due to rust-lang/rust#18804, make sure this is not generic!
  40. pub unsafe fn register(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
  41. use core::mem;
  42. /// A thread destructor.
  43. type Dtor = unsafe extern fn(dtor: unsafe extern fn(*mut u8), arg: *mut u8, dso_handle: *mut u8) -> libc::c_int;
  44. mem::transmute::<*const libc::c_void, Dtor>(__cxa_thread_atexit_impl)(dtor, t, &__dso_handle as *const _ as *mut _);
  45. }
  46. }
  47. /// Thread destructors for Mac OS.
  48. #[cfg(target_os = "macos")]
  49. pub mod thread_destructor {
  50. use libc;
  51. /// Does this platform support thread destructors?
  52. ///
  53. /// This will always return true.
  54. #[inline]
  55. pub fn is_supported() -> bool { true }
  56. /// Register a thread destructor.
  57. ///
  58. /// # Safety
  59. ///
  60. /// This is unsafe due to accepting (and dereferencing) raw pointers, as well as running an
  61. /// arbitrary unsafe function.
  62. #[cfg(target_os = "macos")]
  63. pub unsafe fn register(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
  64. extern {
  65. fn _tlv_atexit(dtor: unsafe extern fn(*mut u8), arg: *mut u8);
  66. }
  67. _tlv_atexit(dtor, t);
  68. }
  69. }