<commit_before>//! # The Rust core allocation and collections library
//!
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, normally doesn’t need to be used directly
//! since its contents are re-exported in the [`std` crate](../std/index.html).
//! Crates that use the `#![no_std]` attribute however will typically
//! not depend on `std`, so they’d use this crate instead.
//!
//! ## Boxed values
//!
//! The [`Box`] type is a smart pointer type. There can only be one owner of a
//! [`Box`], and the owner can decide to mutate the contents, which live on the
//! heap.
//!
//! This type can be sent among threads efficiently as the size of a `Box` value
//! is the same as that of a pointer. Tree-like data structures are often built
//! with boxes because each node often has only one owner, the parent.
//!
//! ## Reference counted pointers
//!
//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
//! only allows access to `&T`, a shared reference.
//!
//! This type is useful when inherited mutability (such as using [`Box`]) is too
//! constraining for an application, and is often paired with the [`Cell`] or
//! [`RefCell`] types in order to allow mutation.
//!
//! ## Atomically reference counted pointers
//!
//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
//! provides all the same functionality of [`Rc`], except it requires that the
//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
//! sendable while [`Rc<T>`][`Rc`] is not.
//!
//! This type allows for shared access to the contained data, and is often
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are re-exported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.
//!
//! [`Arc`]: sync
//! [`Box`]: boxed
//! [`Cell`]: core::cell
//! [`Rc`]: rc
//! [`RefCell`]: core::cell

// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
// rustc itself never sets the feature, so this line has no affect there.
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
    html_playground_url = "https://play.rust-lang.org/",
    issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
    test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(
    not(bootstrap),
    doc(cfg_hide(not(test), not(any(test, bootstrap)), target_has_atomic = "ptr"))
)]
#![no_std]
#![needs_allocator]
#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]
#![allow(explicit_outlives_requirements)]
#![deny(unsafe_op_in_unsafe_fn)]
#![feature(rustc_allow_const_fn_unstable)]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(allocator_api)]
#![feature(array_chunks)]
#![feature(array_methods)]
#![feature(array_windows)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(async_stream)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_sanitize)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
#![feature(const_fn_trait_bound)]
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(const_trait_impl)]
#![feature(destructuring_assignment)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(exclusive_range_pattern)]
#![feature(extend_one)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(fundamental)]
#![feature(inplace_iteration)]
// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]`
// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad
// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs
// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing.
#![feature(intra_doc_pointers)]
#![feature(iter_advance_by)]
#![feature(iter_zip)]
#![feature(lang_items)]
#![feature(layout_for_ptr)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(nll)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(auto_traits)]
#![feature(option_result_unwrap_unchecked)]
#![feature(pattern)]
#![feature(ptr_internals)]
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(min_specialization)]
#![feature(set_ptr_value)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(slice_range)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(unsized_fn_params)]
#![feature(allocator_internals)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
#![feature(alloc_layout_extra)]
#![feature(trusted_random_access)]
#![feature(try_trait_v2)]
#![feature(associated_type_bounds)]
#![feature(slice_group_by)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
// Allow testing this library

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;

// Heaps provided for low-level allocation strategies

pub mod alloc;

// Primitive types using the heaps above

// Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
pub mod borrow;
pub mod collections;
pub mod fmt;
pub mod prelude;
pub mod raw_vec;
pub mod rc;
pub mod slice;
pub mod str;
pub mod string;
#[cfg(target_has_atomic = "ptr")]
pub mod sync;
#[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
pub mod task;
#[cfg(test)]
mod tests;
pub mod vec;

#[doc(hidden)]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
pub mod __export {
    pub use core::format_args;
}
<commit_msg>Cfg hide more conditions for alloc<commit_after>//! # The Rust core allocation and collections library
//!
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, normally doesn’t need to be used directly
//! since its contents are re-exported in the [`std` crate](../std/index.html).
//! Crates that use the `#![no_std]` attribute however will typically
//! not depend on `std`, so they’d use this crate instead.
//!
//! ## Boxed values
//!
//! The [`Box`] type is a smart pointer type. There can only be one owner of a
//! [`Box`], and the owner can decide to mutate the contents, which live on the
//! heap.
//!
//! This type can be sent among threads efficiently as the size of a `Box` value
//! is the same as that of a pointer. Tree-like data structures are often built
//! with boxes because each node often has only one owner, the parent.
//!
//! ## Reference counted pointers
//!
//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
//! only allows access to `&T`, a shared reference.
//!
//! This type is useful when inherited mutability (such as using [`Box`]) is too
//! constraining for an application, and is often paired with the [`Cell`] or
//! [`RefCell`] types in order to allow mutation.
//!
//! ## Atomically reference counted pointers
//!
//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
//! provides all the same functionality of [`Rc`], except it requires that the
//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
//! sendable while [`Rc<T>`][`Rc`] is not.
//!
//! This type allows for shared access to the contained data, and is often
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are re-exported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
//! default global allocator. It is not compatible with the libc allocator API.
//!
//! [`Arc`]: sync
//! [`Box`]: boxed
//! [`Cell`]: core::cell
//! [`Rc`]: rc
//! [`RefCell`]: core::cell

// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
// rustc itself never sets the feature, so this line has no affect there.
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
    html_playground_url = "https://play.rust-lang.org/",
    issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
    test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(
    not(bootstrap),
    doc(cfg_hide(
        not(test),
        not(any(test, bootstrap)),
        any(not(feature = "miri-test-libstd"), test, doctest),
        target_has_atomic = "ptr"
    ))
)]
#![no_std]
#![needs_allocator]
#![warn(deprecated_in_future)]
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]
#![allow(explicit_outlives_requirements)]
#![deny(unsafe_op_in_unsafe_fn)]
#![feature(rustc_allow_const_fn_unstable)]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(allocator_api)]
#![feature(array_chunks)]
#![feature(array_methods)]
#![feature(array_windows)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(async_stream)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_sanitize)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
#![feature(const_fn_trait_bound)]
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(const_trait_impl)]
#![feature(destructuring_assignment)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(exclusive_range_pattern)]
#![feature(extend_one)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(fundamental)]
#![feature(inplace_iteration)]
// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]`
// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad
// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs
// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing.
#![feature(intra_doc_pointers)]
#![feature(iter_advance_by)]
#![feature(iter_zip)]
#![feature(lang_items)]
#![feature(layout_for_ptr)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(nll)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(auto_traits)]
#![feature(option_result_unwrap_unchecked)]
#![feature(pattern)]
#![feature(ptr_internals)]
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(min_specialization)]
#![feature(set_ptr_value)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(slice_range)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(unsized_fn_params)]
#![feature(allocator_internals)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
#![feature(alloc_layout_extra)]
#![feature(trusted_random_access)]
#![feature(try_trait_v2)]
#![feature(associated_type_bounds)]
#![feature(slice_group_by)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
// Allow testing this library

#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;

// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
mod macros;

// Heaps provided for low-level allocation strategies

pub mod alloc;

// Primitive types using the heaps above

// Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
pub mod borrow;
pub mod collections;
pub mod fmt;
pub mod prelude;
pub mod raw_vec;
pub mod rc;
pub mod slice;
pub mod str;
pub mod string;
#[cfg(target_has_atomic = "ptr")]
pub mod sync;
#[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
pub mod task;
#[cfg(test)]
mod tests;
pub mod vec;

#[doc(hidden)]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
pub mod __export {
    pub use core::format_args;
}
<|endoftext|>


<commit_before>#![stable(feature = "core_hint", since = "1.27.0")]

//! Hints to compiler that affects how code should be emitted or optimized.

use crate::intrinsics;

/// Informs the compiler that this point in the code is not reachable, enabling
/// further optimizations.
///
/// # Safety
///
/// Reaching this function is completely *undefined behavior* (UB). In
/// particular, the compiler assumes that all UB must never happen, and
/// therefore will eliminate all branches that reach to a call to
/// `unreachable_unchecked()`.
///
/// Like all instances of UB, if this assumption turns out to be wrong, i.e., the
/// `unreachable_unchecked()` call is actually reachable among all possible
/// control flow, the compiler will apply the wrong optimization strategy, and
/// may sometimes even corrupt seemingly unrelated code, causing
/// difficult-to-debug problems.
///
/// Use this function only when you can prove that the code will never call it.
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
/// optimizations but will panic when executed.
///
///
/// # Example
///
/// ```
/// fn div_1(a: u32, b: u32) -> u32 {
///     use std::hint::unreachable_unchecked;
///
///     // `b.saturating_add(1)` is always positive (not zero),
///     // hence `checked_div` will never return `None`.
///     // Therefore, the else branch is unreachable.
///     a.checked_div(b.saturating_add(1))
///         .unwrap_or_else(|| unsafe { unreachable_unchecked() })
/// }
///
/// assert_eq!(div_1(7, 0), 7);
/// assert_eq!(div_1(9, 1), 4);
/// assert_eq!(div_1(11, u32::MAX), 0);
/// ```
#[inline]
#[stable(feature = "unreachable", since = "1.27.0")]
#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")]
pub const unsafe fn unreachable_unchecked() -> ! {
    // SAFETY: the safety contract for `intrinsics::unreachable` must
    // be upheld by the caller.
    unsafe { intrinsics::unreachable() }
}

/// Emits a machine instruction hinting to the processor that it is running in busy-wait
/// spin-loop ("spin lock").
///
/// For a discussion of different locking strategies and their trade-offs, see
/// [`core::sync::atomic::spin_loop_hint`].
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
///
/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
pub fn spin_loop() {
    #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
    {
        #[cfg(target_arch = "x86")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
            unsafe { crate::arch::x86::_mm_pause() };
        }

        #[cfg(target_arch = "x86_64")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
            unsafe { crate::arch::x86_64::_mm_pause() };
        }
    }

    #[cfg(any(target_arch = "aarch64", all(target_arch = "arm", target_feature = "v6")))]
    {
        #[cfg(target_arch = "aarch64")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
            unsafe { crate::arch::aarch64::__yield() };
        }
        #[cfg(target_arch = "arm")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on arm targets
            // with support for the v6 feature.
            unsafe { crate::arch::arm::__yield() };
        }
    }
}

/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what
/// `black_box` could do.
///
/// [`std::convert::identity`]: https://doc.rust-lang.org/core/convert/fn.identity.html
///
/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can
/// use `dummy` in any possible valid way that Rust code is allowed to without introducing undefined
/// behavior in the calling code. This property makes `black_box` useful for writing code in which
/// certain optimizations are not desired, such as benchmarks.
///
/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
/// extent to which it can block optimisations may vary depending upon the platform and code-gen
/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
#[inline]
#[unstable(feature = "test", issue = "50297")]
#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
pub fn black_box<T>(mut dummy: T) -> T {
    // We need to "use" the argument in some way LLVM can't introspect, and on
    // targets that support it we can typically leverage inline assembly to do
    // this. LLVM's interpretation of inline assembly is that it's, well, a black
    // box. This isn't the greatest implementation since it probably deoptimizes
    // more than we want, but it's so far good enough.

    #[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
    // SAFETY: the inline assembly is a no-op.
    unsafe {
        // FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
        llvm_asm!("" : : "r"(&mut dummy));
    }

    dummy
}
<commit_msg>Fix black_box bug detected by Amanieu<commit_after>#![stable(feature = "core_hint", since = "1.27.0")]

//! Hints to compiler that affects how code should be emitted or optimized.

use crate::intrinsics;

/// Informs the compiler that this point in the code is not reachable, enabling
/// further optimizations.
///
/// # Safety
///
/// Reaching this function is completely *undefined behavior* (UB). In
/// particular, the compiler assumes that all UB must never happen, and
/// therefore will eliminate all branches that reach to a call to
/// `unreachable_unchecked()`.
///
/// Like all instances of UB, if this assumption turns out to be wrong, i.e., the
/// `unreachable_unchecked()` call is actually reachable among all possible
/// control flow, the compiler will apply the wrong optimization strategy, and
/// may sometimes even corrupt seemingly unrelated code, causing
/// difficult-to-debug problems.
///
/// Use this function only when you can prove that the code will never call it.
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
/// optimizations but will panic when executed.
///
///
/// # Example
///
/// ```
/// fn div_1(a: u32, b: u32) -> u32 {
///     use std::hint::unreachable_unchecked;
///
///     // `b.saturating_add(1)` is always positive (not zero),
///     // hence `checked_div` will never return `None`.
///     // Therefore, the else branch is unreachable.
///     a.checked_div(b.saturating_add(1))
///         .unwrap_or_else(|| unsafe { unreachable_unchecked() })
/// }
///
/// assert_eq!(div_1(7, 0), 7);
/// assert_eq!(div_1(9, 1), 4);
/// assert_eq!(div_1(11, u32::MAX), 0);
/// ```
#[inline]
#[stable(feature = "unreachable", since = "1.27.0")]
#[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")]
pub const unsafe fn unreachable_unchecked() -> ! {
    // SAFETY: the safety contract for `intrinsics::unreachable` must
    // be upheld by the caller.
    unsafe { intrinsics::unreachable() }
}

/// Emits a machine instruction hinting to the processor that it is running in busy-wait
/// spin-loop ("spin lock").
///
/// For a discussion of different locking strategies and their trade-offs, see
/// [`core::sync::atomic::spin_loop_hint`].
///
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
/// do anything at all.
///
/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
pub fn spin_loop() {
    #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
    {
        #[cfg(target_arch = "x86")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
            unsafe { crate::arch::x86::_mm_pause() };
        }

        #[cfg(target_arch = "x86_64")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
            unsafe { crate::arch::x86_64::_mm_pause() };
        }
    }

    #[cfg(any(target_arch = "aarch64", all(target_arch = "arm", target_feature = "v6")))]
    {
        #[cfg(target_arch = "aarch64")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
            unsafe { crate::arch::aarch64::__yield() };
        }
        #[cfg(target_arch = "arm")]
        {
            // SAFETY: the `cfg` attr ensures that we only execute this on arm targets
            // with support for the v6 feature.
            unsafe { crate::arch::arm::__yield() };
        }
    }
}

/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what
/// `black_box` could do.
///
/// [`std::convert::identity`]: https://doc.rust-lang.org/core/convert/fn.identity.html
///
/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can
/// use `dummy` in any possible valid way that Rust code is allowed to without introducing undefined
/// behavior in the calling code. This property makes `black_box` useful for writing code in which
/// certain optimizations are not desired, such as benchmarks.
///
/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
/// extent to which it can block optimisations may vary depending upon the platform and code-gen
/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
#[inline]
#[unstable(feature = "test", issue = "50297")]
#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
pub fn black_box<T>(mut dummy: T) -> T {
    // We need to "use" the argument in some way LLVM can't introspect, and on
    // targets that support it we can typically leverage inline assembly to do
    // this. LLVM's interpretation of inline assembly is that it's, well, a black
    // box. This isn't the greatest implementation since it probably deoptimizes
    // more than we want, but it's so far good enough.

    #[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
    // SAFETY: the inline assembly is a no-op.
    unsafe {
        // FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
        llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
    }

    dummy
}
<|endoftext|>


<commit_before>//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

use std::error::Error;

pub use failable::ops::and::FailableAnd;
pub use failable::ops::bool::FailableBool;
pub use failable::ops::not::FailableNot;
pub use failable::ops::xor::FailableXOr;
pub use failable::ops::or::FailableOr;

/// Trait for converting something into a Filter
pub trait IntoFailableFilter<N, E: Error + Sized> {
    type IntoFilt: FailableFilter<N, E>;

    fn into_failable_filter(self) -> Self::IntoFilt;
}

/// All Filters can be turned into Filters
impl<N, E: Error + Sized, I: FailableFilter<N, E>> IntoFailableFilter<N, E> for I {
    type IntoFilt = I;

    fn into_failable_filter(self) -> Self::IntoFilt {
        self
    }
}

pub trait FailableFilter<N, E: Error> {
    /// The function which is used to filter something
    fn filter(&self, &N) -> Result<bool, E>;

    /// Helper to invert a filter.
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let f = (|&a: &usize| { a == 1 }).not();
    ///
    /// assert!(f.filter(&2));
    /// ```
    fn not(self) -> FailableNot<Self>
        where Self: Sized
    {
        FailableNot::new(self)
    }

    /// Helper to connect two filters via logical OR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = a.or(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(c.filter(&2));
    /// assert!(!c.filter(&7));
    /// ```
    fn or<F>(self, other: F) -> FailableOr<Self, F::IntoFilt>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized
    {
        FailableOr::new(self, other.into_failable_filter())
    }

    /// Helper to connect two filters via logical OR and NOT
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = a.or_not(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(!c.filter(&2));
    /// assert!(c.filter(&7));
    /// ```
    fn or_not<F>(self, other: F) -> FailableOr<Self, FailableNot<F::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized,
    {
        self.or(FailableNot::new(other.into_failable_filter()))
    }

    /// Helper to connect three filters via logical OR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = (|&a: &usize| { a == 3 });
    /// let d = a.or3(b, c);
    ///
    /// assert!(d.filter(&1));
    /// assert!(d.filter(&2));
    /// assert!(d.filter(&3));
    /// assert!(!d.filter(&4));
    /// ```
    fn or3<F, F2>(self, other: F, other2: F2) -> FailableOr<Self, FailableOr<F::IntoFilt, F2::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized,
              F2: IntoFailableFilter<N, E> + Sized
    {
        FailableOr::new(self, FailableOr::new(other.into_failable_filter(), other2.into_failable_filter()))
    }

    /// Helper to connect two filters via logical NOR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = a.nor(b); /* !(a == 1 || a == 2) */
    ///
    /// assert!(!c.filter(&1));
    /// assert!(!c.filter(&2));
    /// assert!(c.filter(&3));
    /// assert!(c.filter(&4));
    /// ```
    fn nor<F>(self, other: F) -> FailableNot<FailableOr<Self, F>>
        where Self: Sized,
    {
        FailableNot::new(FailableOr::new(self, other))
    }

    /// Helper to connect two filters via logical XOR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 3 });
    /// let b = (|&a: &usize| { a < 7 });
    /// let c = a.xor(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(c.filter(&3));
    /// assert!(!c.filter(&4));
    /// assert!(!c.filter(&6));
    /// assert!(c.filter(&9));
    /// ```
    fn xor<F>(self, other: F) -> FailableXOr<Self, F>
        where Self: Sized,
    {
        FailableXOr::new(self, other)
    }

    /// Helper to connect two filters via logical AND
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 1 });
    /// let b = (|&a: &usize| { a < 7 });
    /// let c = a.and(b);
    ///
    /// assert!(!c.filter(&1));
    /// assert!(c.filter(&3));
    /// assert!(c.filter(&4));
    /// assert!(c.filter(&6));
    /// assert!(!c.filter(&9));
    /// ```
    fn and<F>(self, other: F) -> FailableAnd<Self, F::IntoFilt>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized
    {
        FailableAnd::new(self, other.into_failable_filter())
    }

    /// Helper to connect three filters via logical AND
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 1 });
    /// let b = (|&a: &usize| { a < 20 });
    /// let c = (|&a: &usize| { a % 2 == 0 });
    /// let d = a.and3(b, c);
    ///
    /// assert!(!d.filter(&1));
    /// assert!(!d.filter(&3));
    /// assert!(d.filter(&8));
    /// assert!(d.filter(&10));
    /// assert!(d.filter(&14));
    /// assert!(!d.filter(&15));
    /// assert!(!d.filter(&19));
    /// ```
    fn and3<F, F2>(self, other: F, other2: F2) -> FailableAnd<Self, FailableAnd<F::IntoFilt, F2::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized,
              F2: IntoFailableFilter<N, E> + Sized
    {
        FailableAnd::new(self, FailableAnd::new(other.into_failable_filter(), other2.into_failable_filter()))
    }

    /// Helper to connect two filters via logical AND and NOT
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 10 });
    /// let b = (|&a: &usize| { a < 20 });
    /// let c = a.and_not(b);
    ///
    /// assert!(!c.filter(&1));
    /// assert!(!c.filter(&3));
    /// assert!(!c.filter(&8));
    /// assert!(!c.filter(&11));
    /// assert!(c.filter(&24));
    /// assert!(c.filter(&25));
    /// assert!(c.filter(&29));
    /// ```
    fn and_not<F>(self, other: F) -> FailableAnd<Self, FailableNot<F::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized
    {
        self.and(FailableNot::new(other.into_failable_filter()))
    }

    /// Helper to connect two filters via logical NAND
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 10 });
    /// let b = (|&a: &usize| { a < 20 });
    /// let c = a.nand(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(c.filter(&3));
    /// assert!(c.filter(&8));
    /// assert!(!c.filter(&11));
    /// assert!(!c.filter(&14));
    /// assert!(c.filter(&25));
    /// assert!(c.filter(&29));
    /// ```
    fn nand<F>(self, other: F) -> FailableNot<FailableAnd<Self, F>>
        where Self: Sized,
    {
        FailableNot::new(FailableAnd::new(self, other))
    }

}

<commit_msg>Implement FailableFilter for all closures<commit_after>//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

use std::error::Error;

pub use failable::ops::and::FailableAnd;
pub use failable::ops::bool::FailableBool;
pub use failable::ops::not::FailableNot;
pub use failable::ops::xor::FailableXOr;
pub use failable::ops::or::FailableOr;

/// Trait for converting something into a Filter
pub trait IntoFailableFilter<N, E: Error + Sized> {
    type IntoFilt: FailableFilter<N, E>;

    fn into_failable_filter(self) -> Self::IntoFilt;
}

/// All Filters can be turned into Filters
impl<N, E: Error + Sized, I: FailableFilter<N, E>> IntoFailableFilter<N, E> for I {
    type IntoFilt = I;

    fn into_failable_filter(self) -> Self::IntoFilt {
        self
    }
}

pub trait FailableFilter<N, E: Error> {
    /// The function which is used to filter something
    fn filter(&self, &N) -> Result<bool, E>;

    /// Helper to invert a filter.
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let f = (|&a: &usize| { a == 1 }).not();
    ///
    /// assert!(f.filter(&2));
    /// ```
    fn not(self) -> FailableNot<Self>
        where Self: Sized
    {
        FailableNot::new(self)
    }

    /// Helper to connect two filters via logical OR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = a.or(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(c.filter(&2));
    /// assert!(!c.filter(&7));
    /// ```
    fn or<F>(self, other: F) -> FailableOr<Self, F::IntoFilt>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized
    {
        FailableOr::new(self, other.into_failable_filter())
    }

    /// Helper to connect two filters via logical OR and NOT
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = a.or_not(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(!c.filter(&2));
    /// assert!(c.filter(&7));
    /// ```
    fn or_not<F>(self, other: F) -> FailableOr<Self, FailableNot<F::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized,
    {
        self.or(FailableNot::new(other.into_failable_filter()))
    }

    /// Helper to connect three filters via logical OR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = (|&a: &usize| { a == 3 });
    /// let d = a.or3(b, c);
    ///
    /// assert!(d.filter(&1));
    /// assert!(d.filter(&2));
    /// assert!(d.filter(&3));
    /// assert!(!d.filter(&4));
    /// ```
    fn or3<F, F2>(self, other: F, other2: F2) -> FailableOr<Self, FailableOr<F::IntoFilt, F2::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized,
              F2: IntoFailableFilter<N, E> + Sized
    {
        FailableOr::new(self, FailableOr::new(other.into_failable_filter(), other2.into_failable_filter()))
    }

    /// Helper to connect two filters via logical NOR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a == 1 });
    /// let b = (|&a: &usize| { a == 2 });
    /// let c = a.nor(b); /* !(a == 1 || a == 2) */
    ///
    /// assert!(!c.filter(&1));
    /// assert!(!c.filter(&2));
    /// assert!(c.filter(&3));
    /// assert!(c.filter(&4));
    /// ```
    fn nor<F>(self, other: F) -> FailableNot<FailableOr<Self, F>>
        where Self: Sized,
    {
        FailableNot::new(FailableOr::new(self, other))
    }

    /// Helper to connect two filters via logical XOR
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 3 });
    /// let b = (|&a: &usize| { a < 7 });
    /// let c = a.xor(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(c.filter(&3));
    /// assert!(!c.filter(&4));
    /// assert!(!c.filter(&6));
    /// assert!(c.filter(&9));
    /// ```
    fn xor<F>(self, other: F) -> FailableXOr<Self, F>
        where Self: Sized,
    {
        FailableXOr::new(self, other)
    }

    /// Helper to connect two filters via logical AND
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 1 });
    /// let b = (|&a: &usize| { a < 7 });
    /// let c = a.and(b);
    ///
    /// assert!(!c.filter(&1));
    /// assert!(c.filter(&3));
    /// assert!(c.filter(&4));
    /// assert!(c.filter(&6));
    /// assert!(!c.filter(&9));
    /// ```
    fn and<F>(self, other: F) -> FailableAnd<Self, F::IntoFilt>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized
    {
        FailableAnd::new(self, other.into_failable_filter())
    }

    /// Helper to connect three filters via logical AND
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 1 });
    /// let b = (|&a: &usize| { a < 20 });
    /// let c = (|&a: &usize| { a % 2 == 0 });
    /// let d = a.and3(b, c);
    ///
    /// assert!(!d.filter(&1));
    /// assert!(!d.filter(&3));
    /// assert!(d.filter(&8));
    /// assert!(d.filter(&10));
    /// assert!(d.filter(&14));
    /// assert!(!d.filter(&15));
    /// assert!(!d.filter(&19));
    /// ```
    fn and3<F, F2>(self, other: F, other2: F2) -> FailableAnd<Self, FailableAnd<F::IntoFilt, F2::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized,
              F2: IntoFailableFilter<N, E> + Sized
    {
        FailableAnd::new(self, FailableAnd::new(other.into_failable_filter(), other2.into_failable_filter()))
    }

    /// Helper to connect two filters via logical AND and NOT
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 10 });
    /// let b = (|&a: &usize| { a < 20 });
    /// let c = a.and_not(b);
    ///
    /// assert!(!c.filter(&1));
    /// assert!(!c.filter(&3));
    /// assert!(!c.filter(&8));
    /// assert!(!c.filter(&11));
    /// assert!(c.filter(&24));
    /// assert!(c.filter(&25));
    /// assert!(c.filter(&29));
    /// ```
    fn and_not<F>(self, other: F) -> FailableAnd<Self, FailableNot<F::IntoFilt>>
        where Self: Sized,
              F: IntoFailableFilter<N, E> + Sized
    {
        self.and(FailableNot::new(other.into_failable_filter()))
    }

    /// Helper to connect two filters via logical NAND
    ///
    /// ```
    /// use filters::filter::Filter;
    ///
    /// let a = (|&a: &usize| { a > 10 });
    /// let b = (|&a: &usize| { a < 20 });
    /// let c = a.nand(b);
    ///
    /// assert!(c.filter(&1));
    /// assert!(c.filter(&3));
    /// assert!(c.filter(&8));
    /// assert!(!c.filter(&11));
    /// assert!(!c.filter(&14));
    /// assert!(c.filter(&25));
    /// assert!(c.filter(&29));
    /// ```
    fn nand<F>(self, other: F) -> FailableNot<FailableAnd<Self, F>>
        where Self: Sized,
    {
        FailableNot::new(FailableAnd::new(self, other))
    }

}

/// All closures that take a ref to something and return Result<bool, E> are failable filters
impl<I, E: Error, T: Fn(&I) -> Result<bool, E>> FailableFilter<I, E> for T {
    fn filter(&self, other: &I) -> Result<bool, E>{
        self(other)
    }
}

<|endoftext|>


<commit_before>use libc::c_int;
use wayland_sys::server::signal::wl_signal_add;
use wlroots_sys::{pid_t, wl_client, wl_display, wlr_compositor, wlr_xwayland, wlr_xwayland_create,
                  wlr_xwayland_destroy, wlr_xwayland_set_cursor};

use super::{XWaylandManager, XWaylandManagerHandler};

pub struct XWaylandServer {
    xwayland: *mut wlr_xwayland,
    manager: Box<XWaylandManager>
}

impl XWaylandServer {
    pub(crate) unsafe fn new(display: *mut wl_display,
                             compositor: *mut wlr_compositor,
                             manager: Box<XWaylandManagerHandler>,
                             lazy: bool)
                             -> Self {
        let xwayland = wlr_xwayland_create(display, compositor, lazy);
        if xwayland.is_null() {
            panic!("Could not start XWayland server")
        }
        let mut manager = XWaylandManager::new(manager);
        wl_signal_add(&mut (*xwayland).events.ready as *mut _ as _,
                      manager.on_ready_listener() as *mut _ as _);
        wl_signal_add(&mut (*xwayland).events.new_surface as *mut _ as _,
                      manager.new_surface_listener() as *mut _ as _);
        XWaylandServer { xwayland, manager }
    }

    /// Get the PID of the XWayland server.
    pub fn pid(&self) -> pid_t {
        unsafe { (*self.xwayland).pid }
    }

    pub fn display(&self) -> c_int {
        unsafe { (*self.xwayland).display }
    }

    pub fn x_fd(&self) -> [c_int; 2] {
        unsafe { (*self.xwayland).x_fd }
    }

    pub fn wl_fd(&self) -> [c_int; 2] {
        unsafe { (*self.xwayland).wl_fd }
    }

    pub fn wm_fd(&self) -> [c_int; 2] {
        unsafe { (*self.xwayland).wm_fd }
    }

    pub fn wl_client(&self) -> *mut wl_client {
        unsafe { (*self.xwayland).client }
    }

    pub fn set_cursor(&mut self,
                      bytes: &mut [u8],
                      stride: u32,
                      width: u32,
                      height: u32,
                      hotspot_x: i32,
                      hotspot_y: i32) {
        unsafe {
            wlr_xwayland_set_cursor(self.xwayland,
                                    bytes.as_mut_ptr(),
                                    stride,
                                    width,
                                    height,
                                    hotspot_x,
                                    hotspot_y)
        }
    }
}

impl Drop for XWaylandServer {
    fn drop(&mut self) {
        unsafe { wlr_xwayland_destroy(self.xwayland) }
    }
}
<commit_msg>Fixed warnings<commit_after>use libc::c_int;
use wayland_sys::server::signal::wl_signal_add;
use wlroots_sys::{pid_t, wl_client, wl_display, wlr_compositor, wlr_xwayland, wlr_xwayland_create,
                  wlr_xwayland_destroy, wlr_xwayland_set_cursor};

use super::{XWaylandManager, XWaylandManagerHandler};

#[allow(dead_code)]
pub struct XWaylandServer {
    xwayland: *mut wlr_xwayland,
    manager: Box<XWaylandManager>
}

impl XWaylandServer {
    pub(crate) unsafe fn new(display: *mut wl_display,
                             compositor: *mut wlr_compositor,
                             manager: Box<XWaylandManagerHandler>,
                             lazy: bool)
                             -> Self {
        let xwayland = wlr_xwayland_create(display, compositor, lazy);
        if xwayland.is_null() {
            panic!("Could not start XWayland server")
        }
        let mut manager = XWaylandManager::new(manager);
        wl_signal_add(&mut (*xwayland).events.ready as *mut _ as _,
                      manager.on_ready_listener() as *mut _ as _);
        wl_signal_add(&mut (*xwayland).events.new_surface as *mut _ as _,
                      manager.new_surface_listener() as *mut _ as _);
        XWaylandServer { xwayland, manager }
    }

    /// Get the PID of the XWayland server.
    pub fn pid(&self) -> pid_t {
        unsafe { (*self.xwayland).pid }
    }

    pub fn display(&self) -> c_int {
        unsafe { (*self.xwayland).display }
    }

    pub fn x_fd(&self) -> [c_int; 2] {
        unsafe { (*self.xwayland).x_fd }
    }

    pub fn wl_fd(&self) -> [c_int; 2] {
        unsafe { (*self.xwayland).wl_fd }
    }

    pub fn wm_fd(&self) -> [c_int; 2] {
        unsafe { (*self.xwayland).wm_fd }
    }

    pub fn wl_client(&self) -> *mut wl_client {
        unsafe { (*self.xwayland).client }
    }

    pub fn set_cursor(&mut self,
                      bytes: &mut [u8],
                      stride: u32,
                      width: u32,
                      height: u32,
                      hotspot_x: i32,
                      hotspot_y: i32) {
        unsafe {
            wlr_xwayland_set_cursor(self.xwayland,
                                    bytes.as_mut_ptr(),
                                    stride,
                                    width,
                                    height,
                                    hotspot_x,
                                    hotspot_y)
        }
    }
}

impl Drop for XWaylandServer {
    fn drop(&mut self) {
        unsafe { wlr_xwayland_destroy(self.xwayland) }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core_foundation::base::{CFRelease, CFRetain, CFTypeID, CFTypeRef, TCFType};

use libc::{c_void, size_t};
use std::mem;
use std::ptr;

pub type CGDataProviderGetBytesCallback = *const u8;
pub type CGDataProviderReleaseInfoCallback = *const u8;
pub type CGDataProviderRewindCallback = *const u8;
pub type CGDataProviderSkipBytesCallback = *const u8;
pub type CGDataProviderSkipForwardCallback = *const u8;

pub type CGDataProviderGetBytePointerCallback = *const u8;
pub type CGDataProviderGetBytesAtOffsetCallback = *const u8;
pub type CGDataProviderReleaseBytePointerCallback = *const u8;
pub type CGDataProviderReleaseDataCallback = *const u8;
pub type CGDataProviderGetBytesAtPositionCallback = *const u8;

struct __CGDataProvider;

pub type CGDataProviderRef = *const __CGDataProvider;

pub struct CGDataProvider {
    obj: CGDataProviderRef,
}

impl Drop for CGDataProvider {
    fn drop(&mut self) {
        unsafe {
            CFRelease(self.as_CFTypeRef())
        }
    }
}

impl TCFType<CGDataProviderRef> for CGDataProvider {
    #[inline]
    fn as_concrete_TypeRef(&self) -> CGDataProviderRef {
        self.obj
    }

    #[inline]
    unsafe fn wrap_under_get_rule(reference: CGDataProviderRef) -> CGDataProvider {
        let reference: CGDataProviderRef = mem::transmute(CFRetain(mem::transmute(reference)));
        TCFType::wrap_under_create_rule(reference)
    }

    #[inline]
    fn as_CFTypeRef(&self) -> CFTypeRef {
        unsafe {
            mem::transmute(self.as_concrete_TypeRef())
        }
    }

    #[inline]
    unsafe fn wrap_under_create_rule(obj: CGDataProviderRef) -> CGDataProvider {
        CGDataProvider {
            obj: obj,
        }
    }

    #[inline]
    fn type_id(_: Option<CGDataProvider>) -> CFTypeID {
        unsafe {
            CGDataProviderGetTypeID()
        }
    }
}

impl CGDataProvider {
    pub fn from_buffer(buffer: &[u8]) -> CGDataProvider {
        unsafe {
            let result = CGDataProviderCreateWithData(ptr::mut_null(),
                                                      buffer.as_ptr() as *const c_void,
                                                      buffer.len() as u64,
                                                      ptr::null());
            TCFType::wrap_under_create_rule(result)
        }
    }
}

#[link(name = "ApplicationServices", kind = "framework")]
extern {
    //fn CGDataProviderCopyData
    //fn CGDataProviderCreateDirect
    //fn CGDataProviderCreateSequential
    //fn CGDataProviderCreateWithCFData
    fn CGDataProviderCreateWithData(info: *mut c_void,
                                    data: *const c_void,
                                    size: size_t,
                                    releaseData: CGDataProviderReleaseDataCallback
                                   ) -> CGDataProviderRef;
    //fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
    //fn CGDataProviderCreateWithURL
    fn CGDataProviderGetTypeID() -> CFTypeID;
    //fn CGDataProviderRelease(provider: CGDataProviderRef);
    //fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef;
}
<commit_msg>Fixes for building 32bit.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core_foundation::base::{CFRelease, CFRetain, CFTypeID, CFTypeRef, TCFType};

use libc::{c_void, size_t};
use std::mem;
use std::ptr;

pub type CGDataProviderGetBytesCallback = *const u8;
pub type CGDataProviderReleaseInfoCallback = *const u8;
pub type CGDataProviderRewindCallback = *const u8;
pub type CGDataProviderSkipBytesCallback = *const u8;
pub type CGDataProviderSkipForwardCallback = *const u8;

pub type CGDataProviderGetBytePointerCallback = *const u8;
pub type CGDataProviderGetBytesAtOffsetCallback = *const u8;
pub type CGDataProviderReleaseBytePointerCallback = *const u8;
pub type CGDataProviderReleaseDataCallback = *const u8;
pub type CGDataProviderGetBytesAtPositionCallback = *const u8;

struct __CGDataProvider;

pub type CGDataProviderRef = *const __CGDataProvider;

pub struct CGDataProvider {
    obj: CGDataProviderRef,
}

impl Drop for CGDataProvider {
    fn drop(&mut self) {
        unsafe {
            CFRelease(self.as_CFTypeRef())
        }
    }
}

impl TCFType<CGDataProviderRef> for CGDataProvider {
    #[inline]
    fn as_concrete_TypeRef(&self) -> CGDataProviderRef {
        self.obj
    }

    #[inline]
    unsafe fn wrap_under_get_rule(reference: CGDataProviderRef) -> CGDataProvider {
        let reference: CGDataProviderRef = mem::transmute(CFRetain(mem::transmute(reference)));
        TCFType::wrap_under_create_rule(reference)
    }

    #[inline]
    fn as_CFTypeRef(&self) -> CFTypeRef {
        unsafe {
            mem::transmute(self.as_concrete_TypeRef())
        }
    }

    #[inline]
    unsafe fn wrap_under_create_rule(obj: CGDataProviderRef) -> CGDataProvider {
        CGDataProvider {
            obj: obj,
        }
    }

    #[inline]
    fn type_id(_: Option<CGDataProvider>) -> CFTypeID {
        unsafe {
            CGDataProviderGetTypeID()
        }
    }
}

impl CGDataProvider {
    pub fn from_buffer(buffer: &[u8]) -> CGDataProvider {
        unsafe {
            let result = CGDataProviderCreateWithData(ptr::mut_null(),
                                                      buffer.as_ptr() as *const c_void,
                                                      buffer.len() as size_t,
                                                      ptr::null());
            TCFType::wrap_under_create_rule(result)
        }
    }
}

#[link(name = "ApplicationServices", kind = "framework")]
extern {
    //fn CGDataProviderCopyData
    //fn CGDataProviderCreateDirect
    //fn CGDataProviderCreateSequential
    //fn CGDataProviderCreateWithCFData
    fn CGDataProviderCreateWithData(info: *mut c_void,
                                    data: *const c_void,
                                    size: size_t,
                                    releaseData: CGDataProviderReleaseDataCallback
                                   ) -> CGDataProviderRef;
    //fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
    //fn CGDataProviderCreateWithURL
    fn CGDataProviderGetTypeID() -> CFTypeID;
    //fn CGDataProviderRelease(provider: CGDataProviderRef);
    //fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef;
}
<|endoftext|>


<commit_before>// Code for creating styled buffers

use crate::snippet::{Style, StyledString};

#[derive(Debug)]
pub struct StyledBuffer {
    text: Vec<Vec<StyledChar>>,
}

#[derive(Debug)]
struct StyledChar {
    chr: char,
    style: Style,
}

impl StyledChar {
    fn new(chr: char, style: Style) -> Self {
        StyledChar { chr, style }
    }
}

impl StyledBuffer {
    pub fn new() -> StyledBuffer {
        StyledBuffer { text: vec![] }
    }

    pub fn render(&self) -> Vec<Vec<StyledString>> {
        // Tabs are assumed to have been replaced by spaces in calling code.
        debug_assert!(self.text.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t')));

        let mut output: Vec<Vec<StyledString>> = vec![];
        let mut styled_vec: Vec<StyledString> = vec![];

        for styled_row in &self.text {
            let mut current_style = Style::NoStyle;
            let mut current_text = String::new();

            for sc in styled_row {
                if sc.style != current_style {
                    if !current_text.is_empty() {
                        styled_vec.push(StyledString { text: current_text, style: current_style });
                    }
                    current_style = sc.style;
                    current_text = String::new();
                }
                current_text.push(sc.chr);
            }
            if !current_text.is_empty() {
                styled_vec.push(StyledString { text: current_text, style: current_style });
            }

            // We're done with the row, push and keep going
            output.push(styled_vec);

            styled_vec = vec![];
        }

        output
    }

    fn ensure_lines(&mut self, line: usize) {
        while line >= self.text.len() {
            self.text.push(vec![]);
        }
    }

    pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
        self.ensure_lines(line);
        if col < self.text[line].len() {
            self.text[line][col] = StyledChar::new(chr, style);
        } else {
            let mut i = self.text[line].len();
            while i < col {
                self.text[line].push(StyledChar::new(' ', Style::NoStyle));
                i += 1;
            }
            self.text[line].push(StyledChar::new(chr, style));
        }
    }

    pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
        let mut n = col;
        for c in string.chars() {
            self.putc(line, n, c, style);
            n += 1;
        }
    }

    pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
        self.ensure_lines(line);
        let string_len = string.chars().count();

        // Push the old content over to make room for new content
        for _ in 0..string_len {
            self.text[line].insert(0, StyledChar::new(' ', Style::NoStyle));
        }

        self.puts(line, 0, string, style);
    }

    pub fn append(&mut self, line: usize, string: &str, style: Style) {
        if line >= self.text.len() {
            self.puts(line, 0, string, style);
        } else {
            let col = self.text[line].len();
            self.puts(line, col, string, style);
        }
    }

    pub fn num_lines(&self) -> usize {
        self.text.len()
    }

    pub fn set_style_range(
        &mut self,
        line: usize,
        col_start: usize,
        col_end: usize,
        style: Style,
        overwrite: bool,
    ) {
        for col in col_start..col_end {
            self.set_style(line, col, style, overwrite);
        }
    }

    pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
        if let Some(ref mut line) = self.text.get_mut(line) {
            if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
                if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
                    *s = style;
                }
            }
        }
    }
}
<commit_msg>added default for StyledChar<commit_after>// Code for creating styled buffers

use crate::snippet::{Style, StyledString};

#[derive(Debug)]
pub struct StyledBuffer {
    text: Vec<Vec<StyledChar>>,
}

#[derive(Debug)]
struct StyledChar {
    chr: char,
    style: Style,
}

impl StyledChar {
    fn new(chr: char, style: Style) -> Self {
        StyledChar { chr, style }
    }
}

impl Default for StyledChar {
    fn default() -> Self {
        StyledChar::new(' ', Style::NoStyle)
    }
}

impl StyledBuffer {
    pub fn new() -> StyledBuffer {
        StyledBuffer { text: vec![] }
    }

    pub fn render(&self) -> Vec<Vec<StyledString>> {
        // Tabs are assumed to have been replaced by spaces in calling code.
        debug_assert!(self.text.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t')));

        let mut output: Vec<Vec<StyledString>> = vec![];
        let mut styled_vec: Vec<StyledString> = vec![];

        for styled_row in &self.text {
            let mut current_style = Style::NoStyle;
            let mut current_text = String::new();

            for sc in styled_row {
                if sc.style != current_style {
                    if !current_text.is_empty() {
                        styled_vec.push(StyledString { text: current_text, style: current_style });
                    }
                    current_style = sc.style;
                    current_text = String::new();
                }
                current_text.push(sc.chr);
            }
            if !current_text.is_empty() {
                styled_vec.push(StyledString { text: current_text, style: current_style });
            }

            // We're done with the row, push and keep going
            output.push(styled_vec);

            styled_vec = vec![];
        }

        output
    }

    fn ensure_lines(&mut self, line: usize) {
        while line >= self.text.len() {
            self.text.push(vec![]);
        }
    }

    pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
        self.ensure_lines(line);
        if col < self.text[line].len() {
            self.text[line][col] = StyledChar::new(chr, style);
        } else {
            let mut i = self.text[line].len();
            while i < col {
                self.text[line].push(StyledChar::default());
                i += 1;
            }
            self.text[line].push(StyledChar::new(chr, style));
        }
    }

    pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
        let mut n = col;
        for c in string.chars() {
            self.putc(line, n, c, style);
            n += 1;
        }
    }

    pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
        self.ensure_lines(line);
        let string_len = string.chars().count();

        // Push the old content over to make room for new content
        for _ in 0..string_len {
            self.text[line].insert(0, StyledChar::default());
        }

        self.puts(line, 0, string, style);
    }

    pub fn append(&mut self, line: usize, string: &str, style: Style) {
        if line >= self.text.len() {
            self.puts(line, 0, string, style);
        } else {
            let col = self.text[line].len();
            self.puts(line, col, string, style);
        }
    }

    pub fn num_lines(&self) -> usize {
        self.text.len()
    }

    pub fn set_style_range(
        &mut self,
        line: usize,
        col_start: usize,
        col_end: usize,
        style: Style,
        overwrite: bool,
    ) {
        for col in col_start..col_end {
            self.set_style(line, col, style, overwrite);
        }
    }

    pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
        if let Some(ref mut line) = self.text.get_mut(line) {
            if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
                if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
                    *s = style;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2015 Paul Osborne <osbpau@gmail.com>
//
// Licensed 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.

//! PWM Support for the NXP LPC17xx MCUs

use hal::lpc17xx::peripheral_clock::PeripheralClock::PWM1Clock;
use core::intrinsics::abort;

use self::PWMChannel::*;

#[path="../../util/ioreg.rs"]
#[macro_use] mod ioreg;

const PWM_CLOCK_DIVISOR: u8 = 4;

/// "Channels" correspond to MR1..6 (0 used for period)
#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub enum PWMChannel {
  CHANNEL0 = 0,  // reserved for period
  CHANNEL1,
  CHANNEL2,
  CHANNEL3,
  CHANNEL4,
  CHANNEL5,
  CHANNEL6,
}

impl PWMChannel {

  /// Set the match register for this channel to the provided value
  fn set_mr(&self, value: u32) {
    // note that for whatever reason, the match registers are fragmented
    // across two registers.  They aren't even located next to each other
    // in memory
    match *self {
      CHANNEL0 => { reg::PWM1().mr[0].set_value(value); },
      CHANNEL1 => { reg::PWM1().mr[1].set_value(value); },
      CHANNEL2 => { reg::PWM1().mr[2].set_value(value); },
      CHANNEL3 => { reg::PWM1().mr[3].set_value(value); },
      CHANNEL4 => { reg::PWM1().mr2[0].set_value(value); },
      CHANNEL5 => { reg::PWM1().mr2[1].set_value(value); },
      CHANNEL6 => { reg::PWM1().mr2[2].set_value(value); },
    };
  }
}

/// calculate the number of PWM clock ticks for the given number of microseconds
fn pwm_us_to_ticks(us: u32) -> u32 {
  let pwm_clock_frequency_hz: u32 = PWM1Clock.frequency();
  let pwm_clock_frequency_mhz: u32 = pwm_clock_frequency_hz / 1_000_000;
  return pwm_clock_frequency_mhz * us;
}

#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub struct PWM {
  channel: PWMChannel,
  period_us: u32,
  pulsewidth_us: u32,
}

impl PWM {

  /// Create a new PWM Output on the provided channel
  pub fn new(channel: PWMChannel) -> PWM {
    PWM1Clock.enable();
    PWM1Clock.set_divisor(PWM_CLOCK_DIVISOR);
    reg::PWM1().pr.set_value(0);  // no prescaler

    // single PWM mode (reset TC on match 0 for Ch0)
    reg::PWM1().mcr.set_pwmmr0r(true);

    // enable PWM output on this channel
    match channel {
      CHANNEL0 => { unsafe { abort() } },  // CHANNEL0 reserved for internal use
      CHANNEL1 => { reg::PWM1().pcr.set_pwmena1(true); },
      CHANNEL2 => { reg::PWM1().pcr.set_pwmena2(true); },
      CHANNEL3 => { reg::PWM1().pcr.set_pwmena3(true); },
      CHANNEL4 => { reg::PWM1().pcr.set_pwmena4(true); },
      CHANNEL5 => { reg::PWM1().pcr.set_pwmena5(true); },
      CHANNEL6 => { reg::PWM1().pcr.set_pwmena6(true); },
    };

    let pwm = PWM {
      channel: channel,
      period_us: 20_000,  // 20ms is pretty common
      pulsewidth_us: 0,
    };

    pwm.update_period();
    pwm.update_pulsewidth();
    pwm
  }

  /// Update the PWM Signal based on the current state
  fn update_period(&self) {
    // Put the counter into reset and disable the counter
    reg::PWM1().tcr
      .set_ctr_en(reg::PWM1_tcr_ctr_en::DISABLED)
      .set_ctr_reset(reg::PWM1_tcr_ctr_reset::RESET)
      .set_pwm_enable(reg::PWM1_tcr_pwm_enable::DISABLED);

    // setup match register to ticks per period on CH0
    CHANNEL0.set_mr(pwm_us_to_ticks(self.period_us));

    // TODO(posborne): recalculate other registers based on the new period?

    // set the channel latch to update CH0 and CHN
    reg::PWM1().ler.set_value(1 << CHANNEL0 as u32);

    // enable counter and pwm; clear reset
    reg::PWM1().tcr
      .set_ctr_en(reg::PWM1_tcr_ctr_en::ENABLED)
      .set_ctr_reset(reg::PWM1_tcr_ctr_reset::CLEAR_RESET)
      .set_pwm_enable(reg::PWM1_tcr_pwm_enable::ENABLED);
  }

  fn update_pulsewidth(&self) {
    let mut pulsewidth_ticks: u32 = pwm_us_to_ticks(self.pulsewidth_us);
    if pulsewidth_ticks == reg::PWM1().mr[0].get().raw() {
      // avoid making it equal or there is a 1 cycle dropout
      pulsewidth_ticks = pulsewidth_ticks + 1;
    }
    self.channel.set_mr(pulsewidth_ticks);
    reg::PWM1().ler.set_value(1 << self.channel as u32);
  }

}

/// Implementation of Generic PWMOutput trait for LPC17xx
impl ::hal::pwm::PWMOutput for PWM {
  fn set_period_us(&mut self, period_us: u32) {
    self.period_us = period_us;
    self.update_period();
  }

  fn get_period_us(&self) -> u32 {
    self.period_us
  }

  fn set_pulsewidth_us(&mut self, pulsewidth_us: u32) {
    self.pulsewidth_us = pulsewidth_us;
    self.update_pulsewidth();
  }

  fn get_pulsewidth_us(&self) -> u32 {
    self.pulsewidth_us
  }
}

/// LPC17xx PWM Register Definitions (User Manual: 24.6)
mod reg {
  use volatile_cell::VolatileCell;
  use core::ops::Drop;

  ioregs!(PWM1@0x40018000 = {
    /// Interrupt Register. The IR can be written to clear
    /// interrupts. The IR can be read to identify which of eight
    /// possible interrupt sources are pending.
    0x00 => reg32 ir {
      0  => irq_mr0,  //= Interrupt flag for PWM match channel 0.
      1  => irq_mr1,  //= Interrupt flag for PWM match channel 1.
      2  => irq_mr2,  //= Interrupt flag for PWM match channel 2.
      3  => irq_mr3,  //= Interrupt flag for PWM match channel 3.
      4  => irq_cap0, //= Interrupt flag for capture input 0
      5  => irq_cap1, //= Interrupt flag for capture input 1.
      // 7:6 Reserved
      8  => irq_mr4,  //= Interrupt flag for PWM match channel 4.
      9  => irq_mr5,  //= Interrupt flag for PWM match channel 5.
      10 => irq_mr6,  //= Interrupt flag for PWM match channel 6.
    }
    /// Timer Control Register. The TCR is used to control the
    /// Timer Counter functions. The Timer Counter can be disabled
    /// or reset through the TCR.
    0x04 => reg32 tcr {
      0 => ctr_en {
         0 => DISABLED,
         1 => ENABLED
      },
      1 => ctr_reset {
        0 => CLEAR_RESET,
        1 => RESET
      },
      // 2 => Reserved
      3 => pwm_enable {
        0 => DISABLED,
        1 => ENABLED
      }
    }
    /// Timer Counter. The 32-bit TC is incremented every PR+1
    /// cycles of PCLK.  The TC is controlled through the TCR.
    0x08 => reg32 tc { 31..0 => value }
    /// Prescale Register. The TC is incremented every PR+1 cycles
    /// of PCLK.
    0x0C => reg32 pr { 31..0 => value }
    /// Prescale Counter. The 32-bit PC is a counter which is
    /// incremented to the value stored in PR. When the value in
    /// PR is reached, the TC is incremented. The PC is observable
    /// and controllable through the bus interface.
    0x10 => reg32 pc { 31..0 => value }
    /// Match Control Register. The MCR is used to control if an
    /// interrupt is generated and if the TC is reset when a Match
    /// occurs.
    0x14 => reg32 mcr {
      0 => pwmmr0i,  //= if set, interrupt on pwmmr0
      1 => pwmmr0r,  //= if set, reset on pwmmr0
      2 => pwmmr0s,  //= if set, stop on pwmmr0

      3 => pwmmr1i,  //= if set, interrupt on pwmmr1
      4 => pwmmr1r,  //= if set, reset on pwmmr1
      5 => pwmmr1s,  //= if set, stop on pwmmr1

      6 => pwmmr2i,  //= if set, interrupt on pwmmr2
      7 => pwmmr2r,  //= if set, reset on pwmmr2
      8 => pwmmr2s,  //= if set, stop on pwmmr2

      9 => pwmmr3i,  //= if set, interrupt on pwmmr3
      10 => pwmmr3r,  //= if set, reset on pwmmr3
      11 => pwmmr3s,  //= if set, stop on pwmmr3

      12 => pwmmr4i,  //= if set, interrupt on pwmmr4
      13 => pwmmr4r,  //= if set, reset on pwmmr4
      14 => pwmmr4s,  //= if set, stop on pwmmr4

      15=> pwmmr5i,  //= if set, interrupt on pwmmr5
      16 => pwmmr5r,  //= if set, reset on pwmmr5
      17 => pwmmr5s,  //= if set, stop on pwmmr5

      18 => pwmmr6i,  //= if set, interrupt on pwmmr6
      19 => pwmmr6r,  //= if set, reset on pwmmr6
      20 => pwmmr6s,  //= if set, stop on pwmmr6
    }
    /// Match Registers (0-3).  MR<N> can be enabled in the MCR to reset
    /// the TC, stop both the TC and PC, and/or generate an
    /// interrupt when it matches the TC.  In addition, a match
    /// between this value and the TC sets any PWM output that is
    /// in single-edge mode, and sets PWM<N + 1> if it is in double-edge mode
    0x18 => reg32 mr[4] { 31..0 => value }
    /// Capture Control Register. The CCR controls which edges of
    /// the capture inputs are used to load the Capture Registers
    /// and whether or not an interrupt is generated when a
    /// capture takes place.
    0x28 => reg32 ccr { 31..0 => value }
    /// Capture Registers (0-3). CR<N> is loaded with the value of the TC
    /// when there is an event on the CAPn.<N> input.
    0x30 => reg32 cr[4] { 31..0 => value }
    /// Match Registers (4-6).  See `mr` registers.  Not sure why
    /// banks are fragmented.
    0x40 => reg32 mr2[3] { 31..0 => value }
    /// PWM Control Register. Enables PWM outputs and selects PWM
    /// channel types as either single edge or double edge
    /// controlled.
    0x4c => reg32 pcr {
      9  => pwmena1,
      10 => pwmena2,
      11 => pwmena3,
      12 => pwmena4,
      13 => pwmena5,
      14 => pwmena6,
    }
    /// Load Enable Register. Enables use of new PWM match
    /// values.
    0x50 => reg32 ler { 31..0 => value }
    /// Count Control Register. The CTCR selects between Timer and
    /// Counter mode, and in Counter mode selects the signal and
    /// edge(s) for counting.
    0x70 => reg32 ctcr {
      0..2 => mode {
        0 => TIMER_MODE,
        1 => COUNTER_MODE_RISING,
        2 => COUNTER_MODE_FALLING,
        3 => COUNTER_MODE_BOTH
      }
    }
  });

}
<commit_msg>pwm: lpc17xx: clearly mark CHANNEL0 as reserved for PWM period use<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2015 Paul Osborne <osbpau@gmail.com>
//
// Licensed 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.

//! PWM Support for the NXP LPC17xx MCUs

use hal::lpc17xx::peripheral_clock::PeripheralClock::PWM1Clock;
use core::intrinsics::abort;

use self::PWMChannel::*;

#[path="../../util/ioreg.rs"]
#[macro_use] mod ioreg;

const PWM_CLOCK_DIVISOR: u8 = 4;

/// "Channels" correspond to MR1..6 (0 used for period)
#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub enum PWMChannel {
  CHANNEL0_PERIOD_RESERVED = 0,  // reserved for period
  CHANNEL1,
  CHANNEL2,
  CHANNEL3,
  CHANNEL4,
  CHANNEL5,
  CHANNEL6,
}

impl PWMChannel {

  /// Set the match register for this channel to the provided value
  fn set_mr(&self, value: u32) {
    // note that for whatever reason, the match registers are fragmented
    // across two registers.  They aren't even located next to each other
    // in memory
    match *self {
      CHANNEL0_PERIOD_RESERVED => { reg::PWM1().mr[0].set_value(value); },
      CHANNEL1 => { reg::PWM1().mr[1].set_value(value); },
      CHANNEL2 => { reg::PWM1().mr[2].set_value(value); },
      CHANNEL3 => { reg::PWM1().mr[3].set_value(value); },
      CHANNEL4 => { reg::PWM1().mr2[0].set_value(value); },
      CHANNEL5 => { reg::PWM1().mr2[1].set_value(value); },
      CHANNEL6 => { reg::PWM1().mr2[2].set_value(value); },
    };
  }
}

/// calculate the number of PWM clock ticks for the given number of microseconds
fn pwm_us_to_ticks(us: u32) -> u32 {
  let pwm_clock_frequency_hz: u32 = PWM1Clock.frequency();
  let pwm_clock_frequency_mhz: u32 = pwm_clock_frequency_hz / 1_000_000;
  return pwm_clock_frequency_mhz * us;
}

#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub struct PWM {
  channel: PWMChannel,
  period_us: u32,
  pulsewidth_us: u32,
}

impl PWM {

  /// Create a new PWM Output on the provided channel
  pub fn new(channel: PWMChannel) -> PWM {
    PWM1Clock.enable();
    PWM1Clock.set_divisor(PWM_CLOCK_DIVISOR);
    reg::PWM1().pr.set_value(0);  // no prescaler

    // single PWM mode (reset TC on match 0 for Ch0)
    reg::PWM1().mcr.set_pwmmr0r(true);

    // enable PWM output on this channel
    match channel {
      CHANNEL0_PERIOD_RESERVED => { unsafe { abort() } },  // CHANNEL0 reserved for internal use
      CHANNEL1 => { reg::PWM1().pcr.set_pwmena1(true); },
      CHANNEL2 => { reg::PWM1().pcr.set_pwmena2(true); },
      CHANNEL3 => { reg::PWM1().pcr.set_pwmena3(true); },
      CHANNEL4 => { reg::PWM1().pcr.set_pwmena4(true); },
      CHANNEL5 => { reg::PWM1().pcr.set_pwmena5(true); },
      CHANNEL6 => { reg::PWM1().pcr.set_pwmena6(true); },
    };

    let pwm = PWM {
      channel: channel,
      period_us: 20_000,  // 20ms is pretty common
      pulsewidth_us: 0,
    };

    pwm.update_period();
    pwm.update_pulsewidth();
    pwm
  }

  /// Update the PWM Signal based on the current state
  fn update_period(&self) {
    // Put the counter into reset and disable the counter
    reg::PWM1().tcr
      .set_ctr_en(reg::PWM1_tcr_ctr_en::DISABLED)
      .set_ctr_reset(reg::PWM1_tcr_ctr_reset::RESET)
      .set_pwm_enable(reg::PWM1_tcr_pwm_enable::DISABLED);

    // setup match register to ticks per period on CH0
    CHANNEL0_PERIOD_RESERVED.set_mr(pwm_us_to_ticks(self.period_us));

    // TODO(posborne): recalculate other registers based on the new period?

    // set the channel latch to update CH0 and CHN
    reg::PWM1().ler.set_value(1 << CHANNEL0_PERIOD_RESERVED as u32);

    // enable counter and pwm; clear reset
    reg::PWM1().tcr
      .set_ctr_en(reg::PWM1_tcr_ctr_en::ENABLED)
      .set_ctr_reset(reg::PWM1_tcr_ctr_reset::CLEAR_RESET)
      .set_pwm_enable(reg::PWM1_tcr_pwm_enable::ENABLED);
  }

  fn update_pulsewidth(&self) {
    let mut pulsewidth_ticks: u32 = pwm_us_to_ticks(self.pulsewidth_us);
    if pulsewidth_ticks == reg::PWM1().mr[0].get().raw() {
      // avoid making it equal or there is a 1 cycle dropout
      pulsewidth_ticks = pulsewidth_ticks + 1;
    }
    self.channel.set_mr(pulsewidth_ticks);
    reg::PWM1().ler.set_value(1 << self.channel as u32);
  }

}

/// Implementation of Generic PWMOutput trait for LPC17xx
impl ::hal::pwm::PWMOutput for PWM {
  fn set_period_us(&mut self, period_us: u32) {
    self.period_us = period_us;
    self.update_period();
  }

  fn get_period_us(&self) -> u32 {
    self.period_us
  }

  fn set_pulsewidth_us(&mut self, pulsewidth_us: u32) {
    self.pulsewidth_us = pulsewidth_us;
    self.update_pulsewidth();
  }

  fn get_pulsewidth_us(&self) -> u32 {
    self.pulsewidth_us
  }
}

/// LPC17xx PWM Register Definitions (User Manual: 24.6)
mod reg {
  use volatile_cell::VolatileCell;
  use core::ops::Drop;

  ioregs!(PWM1@0x40018000 = {
    /// Interrupt Register. The IR can be written to clear
    /// interrupts. The IR can be read to identify which of eight
    /// possible interrupt sources are pending.
    0x00 => reg32 ir {
      0  => irq_mr0,  //= Interrupt flag for PWM match channel 0.
      1  => irq_mr1,  //= Interrupt flag for PWM match channel 1.
      2  => irq_mr2,  //= Interrupt flag for PWM match channel 2.
      3  => irq_mr3,  //= Interrupt flag for PWM match channel 3.
      4  => irq_cap0, //= Interrupt flag for capture input 0
      5  => irq_cap1, //= Interrupt flag for capture input 1.
      // 7:6 Reserved
      8  => irq_mr4,  //= Interrupt flag for PWM match channel 4.
      9  => irq_mr5,  //= Interrupt flag for PWM match channel 5.
      10 => irq_mr6,  //= Interrupt flag for PWM match channel 6.
    }
    /// Timer Control Register. The TCR is used to control the
    /// Timer Counter functions. The Timer Counter can be disabled
    /// or reset through the TCR.
    0x04 => reg32 tcr {
      0 => ctr_en {
         0 => DISABLED,
         1 => ENABLED
      },
      1 => ctr_reset {
        0 => CLEAR_RESET,
        1 => RESET
      },
      // 2 => Reserved
      3 => pwm_enable {
        0 => DISABLED,
        1 => ENABLED
      }
    }
    /// Timer Counter. The 32-bit TC is incremented every PR+1
    /// cycles of PCLK.  The TC is controlled through the TCR.
    0x08 => reg32 tc { 31..0 => value }
    /// Prescale Register. The TC is incremented every PR+1 cycles
    /// of PCLK.
    0x0C => reg32 pr { 31..0 => value }
    /// Prescale Counter. The 32-bit PC is a counter which is
    /// incremented to the value stored in PR. When the value in
    /// PR is reached, the TC is incremented. The PC is observable
    /// and controllable through the bus interface.
    0x10 => reg32 pc { 31..0 => value }
    /// Match Control Register. The MCR is used to control if an
    /// interrupt is generated and if the TC is reset when a Match
    /// occurs.
    0x14 => reg32 mcr {
      0 => pwmmr0i,  //= if set, interrupt on pwmmr0
      1 => pwmmr0r,  //= if set, reset on pwmmr0
      2 => pwmmr0s,  //= if set, stop on pwmmr0

      3 => pwmmr1i,  //= if set, interrupt on pwmmr1
      4 => pwmmr1r,  //= if set, reset on pwmmr1
      5 => pwmmr1s,  //= if set, stop on pwmmr1

      6 => pwmmr2i,  //= if set, interrupt on pwmmr2
      7 => pwmmr2r,  //= if set, reset on pwmmr2
      8 => pwmmr2s,  //= if set, stop on pwmmr2

      9 => pwmmr3i,  //= if set, interrupt on pwmmr3
      10 => pwmmr3r,  //= if set, reset on pwmmr3
      11 => pwmmr3s,  //= if set, stop on pwmmr3

      12 => pwmmr4i,  //= if set, interrupt on pwmmr4
      13 => pwmmr4r,  //= if set, reset on pwmmr4
      14 => pwmmr4s,  //= if set, stop on pwmmr4

      15=> pwmmr5i,  //= if set, interrupt on pwmmr5
      16 => pwmmr5r,  //= if set, reset on pwmmr5
      17 => pwmmr5s,  //= if set, stop on pwmmr5

      18 => pwmmr6i,  //= if set, interrupt on pwmmr6
      19 => pwmmr6r,  //= if set, reset on pwmmr6
      20 => pwmmr6s,  //= if set, stop on pwmmr6
    }
    /// Match Registers (0-3).  MR<N> can be enabled in the MCR to reset
    /// the TC, stop both the TC and PC, and/or generate an
    /// interrupt when it matches the TC.  In addition, a match
    /// between this value and the TC sets any PWM output that is
    /// in single-edge mode, and sets PWM<N + 1> if it is in double-edge mode
    0x18 => reg32 mr[4] { 31..0 => value }
    /// Capture Control Register. The CCR controls which edges of
    /// the capture inputs are used to load the Capture Registers
    /// and whether or not an interrupt is generated when a
    /// capture takes place.
    0x28 => reg32 ccr { 31..0 => value }
    /// Capture Registers (0-3). CR<N> is loaded with the value of the TC
    /// when there is an event on the CAPn.<N> input.
    0x30 => reg32 cr[4] { 31..0 => value }
    /// Match Registers (4-6).  See `mr` registers.  Not sure why
    /// banks are fragmented.
    0x40 => reg32 mr2[3] { 31..0 => value }
    /// PWM Control Register. Enables PWM outputs and selects PWM
    /// channel types as either single edge or double edge
    /// controlled.
    0x4c => reg32 pcr {
      9  => pwmena1,
      10 => pwmena2,
      11 => pwmena3,
      12 => pwmena4,
      13 => pwmena5,
      14 => pwmena6,
    }
    /// Load Enable Register. Enables use of new PWM match
    /// values.
    0x50 => reg32 ler { 31..0 => value }
    /// Count Control Register. The CTCR selects between Timer and
    /// Counter mode, and in Counter mode selects the signal and
    /// edge(s) for counting.
    0x70 => reg32 ctcr {
      0..2 => mode {
        0 => TIMER_MODE,
        1 => COUNTER_MODE_RISING,
        2 => COUNTER_MODE_FALLING,
        3 => COUNTER_MODE_BOTH
      }
    }
  });

}
<|endoftext|>


<commit_before>extern mod extra;

use std::comm::SharedChan;
use std::io::{Listener, Acceptor};
use std::io::net::ip::SocketAddr;
use std::io::io_error;
use extra::time::precise_time_ns;

use std::io::net::tcp::TcpListener;

use buffer::BufferedStream;

pub use self::request::{RequestBuffer, Request};
pub use self::response::ResponseWriter;

pub mod request;
pub mod response;

pub trait Server: Send + Clone {
	fn handle_request(&self, request: &Request, response: &mut ResponseWriter) -> ();

	// XXX: this could also be implemented on the serve methods
	fn get_config(&self) -> Config;

	/**
	 * Attempt to bind to the address and port and start serving forever.
	 *
	 * This will only return if the initial connection fails or something else blows up.
	 */
    fn serve_forever(self) {
        let config = self.get_config();
        debug!("About to bind to {:?}", config.bind_address);
        let mut acceptor = match TcpListener::bind(config.bind_address).listen() {
            None => {
                error!("bind or listen failed :-(");
                return;
            },
            Some(acceptor) => acceptor,
        };
        debug!("listening");
        let (perf_po, perf_ch) = SharedChan::new();
        do spawn {
            perf_dumper(perf_po);
        }
        loop {
            // OK, we're sort of shadowing an IoError here. Perhaps this should be done in a
            // separate task so that it can safely fail...
            let mut error = None;
            let optstream = io_error::cond.trap(|e| {
                error = Some(e);
            }).inside(|| {
                acceptor.accept()
            });

            let time_start = precise_time_ns();
            if optstream.is_none() {
                debug!("accept failed: {:?}", error);
                // Question: is this the correct thing to do? We should probably be more
                // intelligent, for there are some accept failures that are likely to be
                // permanent, such that continuing would be a very bad idea, such as
                // ENOBUFS/ENOMEM; and some where it should just be ignored, e.g.
                // ECONNABORTED. TODO.
                continue;
            }
            let child_perf_ch = perf_ch.clone();
            let child_self = self.clone();
            do spawn {
                let mut time_start = time_start;
                let mut stream = BufferedStream::new(optstream.unwrap());
                debug!("accepted connection, got {:?}", stream);
                loop {  // A keep-alive loop, condition at end
                    let time_spawned = precise_time_ns();
                    let (request, err_status) = Request::load(&mut stream);
                    let time_request_made = precise_time_ns();
                    let mut response = ~ResponseWriter::new(&mut stream, request);
                    let time_response_made = precise_time_ns();
                    match err_status {
                        Ok(()) => {
                            child_self.handle_request(request, response);
                            // Ensure that we actually do send a response:
                            response.try_write_headers();
                        },
                        Err(status) => {
                            // Uh oh, it's a response that I as a server cannot cope with.
                            // No good user-agent should have caused this, so for the moment
                            // at least I am content to send no body in the response.
                            response.status = status;
                            response.headers.content_length = Some(0);
                            response.write_headers();
                        },
                    }
                    // Ensure the request is flushed, any Transfer-Encoding completed, etc.
                    response.finish_response();
                    let time_finished = precise_time_ns();
                    child_perf_ch.send((time_start, time_spawned, time_request_made, time_response_made, time_finished));

                    // Subsequent requests on this connection have no spawn time
                    time_start = time_finished;

                    if request.close_connection {
                        break;
                    }
                }
            }
        }
    }
}

/// The necessary configuration for an HTTP server.
///
/// At present, only the IP address and port to bind to are needed, but it's possible that other
/// options may turn up later.
pub struct Config {
	bind_address: SocketAddr,
}

static PERF_DUMP_FREQUENCY : u64 = 10_000;

/// Simple function to dump out perf stats every `PERF_DUMP_FREQUENCY` requests
fn perf_dumper(perf_po: Port<(u64, u64, u64, u64, u64)>) {
    // Total durations
    let mut td_spawn = 0u64;
    let mut td_request = 0u64;
    let mut td_response = 0u64;
    let mut td_handle = 0u64;
    let mut td_total = 0u64;
    let mut i = 0u64;
    loop {
        let data = perf_po.recv();
        let (start, spawned, request_made, response_made, finished) = data;
        td_spawn += spawned - start;
        td_request += request_made - spawned;
        td_response += response_made - request_made;
        td_handle += finished - response_made;
        td_total += finished - start;
        i += 1;
        if i % PERF_DUMP_FREQUENCY == 0 {
            println!("");
            println!("{} requests made thus far. Current means:", i);
            println!("- Total:               100%, {:12f}",
                     td_total as f64 / i as f64);
            println!("- Spawn:               {:3f}%, {:12f}",
                     100f64 * td_spawn as f64 / td_total as f64,
                     td_spawn as f64 / i as f64);
            println!("- Load request:        {:3f}%, {:12f}",
                     100f64 * td_request as f64 / td_total as f64,
                     td_request as f64 / i as f64);
            println!("- Initialise response: {:3f}%, {:12f}",
                     100f64 * td_response as f64 / td_total as f64,
                     td_response as f64 / i as f64);
            println!("- Handle:              {:3f}%, {:12f}",
                     100f64 * td_handle as f64 / td_total as f64,
                     td_handle as f64 / i as f64);
        }
    }
}
<commit_msg>Remove "do" usage (removed from the language).<commit_after>extern mod extra;

use std::comm::SharedChan;
use std::io::{Listener, Acceptor};
use std::io::net::ip::SocketAddr;
use std::io::io_error;
use extra::time::precise_time_ns;

use std::io::net::tcp::TcpListener;

use buffer::BufferedStream;

pub use self::request::{RequestBuffer, Request};
pub use self::response::ResponseWriter;

pub mod request;
pub mod response;

pub trait Server: Send + Clone {
	fn handle_request(&self, request: &Request, response: &mut ResponseWriter) -> ();

	// XXX: this could also be implemented on the serve methods
	fn get_config(&self) -> Config;

	/**
	 * Attempt to bind to the address and port and start serving forever.
	 *
	 * This will only return if the initial connection fails or something else blows up.
	 */
    fn serve_forever(self) {
        let config = self.get_config();
        debug!("About to bind to {:?}", config.bind_address);
        let mut acceptor = match TcpListener::bind(config.bind_address).listen() {
            None => {
                error!("bind or listen failed :-(");
                return;
            },
            Some(acceptor) => acceptor,
        };
        debug!("listening");
        let (perf_po, perf_ch) = SharedChan::new();
        spawn(proc() {
            perf_dumper(perf_po);
        });
        loop {
            // OK, we're sort of shadowing an IoError here. Perhaps this should be done in a
            // separate task so that it can safely fail...
            let mut error = None;
            let optstream = io_error::cond.trap(|e| {
                error = Some(e);
            }).inside(|| {
                acceptor.accept()
            });

            let time_start = precise_time_ns();
            if optstream.is_none() {
                debug!("accept failed: {:?}", error);
                // Question: is this the correct thing to do? We should probably be more
                // intelligent, for there are some accept failures that are likely to be
                // permanent, such that continuing would be a very bad idea, such as
                // ENOBUFS/ENOMEM; and some where it should just be ignored, e.g.
                // ECONNABORTED. TODO.
                continue;
            }
            let child_perf_ch = perf_ch.clone();
            let child_self = self.clone();
            spawn(proc() {
                let mut time_start = time_start;
                let mut stream = BufferedStream::new(optstream.unwrap());
                debug!("accepted connection, got {:?}", stream);
                loop {  // A keep-alive loop, condition at end
                    let time_spawned = precise_time_ns();
                    let (request, err_status) = Request::load(&mut stream);
                    let time_request_made = precise_time_ns();
                    let mut response = ~ResponseWriter::new(&mut stream, request);
                    let time_response_made = precise_time_ns();
                    match err_status {
                        Ok(()) => {
                            child_self.handle_request(request, response);
                            // Ensure that we actually do send a response:
                            response.try_write_headers();
                        },
                        Err(status) => {
                            // Uh oh, it's a response that I as a server cannot cope with.
                            // No good user-agent should have caused this, so for the moment
                            // at least I am content to send no body in the response.
                            response.status = status;
                            response.headers.content_length = Some(0);
                            response.write_headers();
                        },
                    }
                    // Ensure the request is flushed, any Transfer-Encoding completed, etc.
                    response.finish_response();
                    let time_finished = precise_time_ns();
                    child_perf_ch.send((time_start, time_spawned, time_request_made, time_response_made, time_finished));

                    // Subsequent requests on this connection have no spawn time
                    time_start = time_finished;

                    if request.close_connection {
                        break;
                    }
                }
            });
        }
    }
}

/// The necessary configuration for an HTTP server.
///
/// At present, only the IP address and port to bind to are needed, but it's possible that other
/// options may turn up later.
pub struct Config {
	bind_address: SocketAddr,
}

static PERF_DUMP_FREQUENCY : u64 = 10_000;

/// Simple function to dump out perf stats every `PERF_DUMP_FREQUENCY` requests
fn perf_dumper(perf_po: Port<(u64, u64, u64, u64, u64)>) {
    // Total durations
    let mut td_spawn = 0u64;
    let mut td_request = 0u64;
    let mut td_response = 0u64;
    let mut td_handle = 0u64;
    let mut td_total = 0u64;
    let mut i = 0u64;
    loop {
        let data = perf_po.recv();
        let (start, spawned, request_made, response_made, finished) = data;
        td_spawn += spawned - start;
        td_request += request_made - spawned;
        td_response += response_made - request_made;
        td_handle += finished - response_made;
        td_total += finished - start;
        i += 1;
        if i % PERF_DUMP_FREQUENCY == 0 {
            println!("");
            println!("{} requests made thus far. Current means:", i);
            println!("- Total:               100%, {:12f}",
                     td_total as f64 / i as f64);
            println!("- Spawn:               {:3f}%, {:12f}",
                     100f64 * td_spawn as f64 / td_total as f64,
                     td_spawn as f64 / i as f64);
            println!("- Load request:        {:3f}%, {:12f}",
                     100f64 * td_request as f64 / td_total as f64,
                     td_request as f64 / i as f64);
            println!("- Initialise response: {:3f}%, {:12f}",
                     100f64 * td_response as f64 / td_total as f64,
                     td_response as f64 / i as f64);
            println!("- Handle:              {:3f}%, {:12f}",
                     100f64 * td_handle as f64 / td_total as f64,
                     td_handle as f64 / i as f64);
        }
    }
}
<|endoftext|>


<commit_before>use lazy_static::lazy_static;

use super::{week2, year2, Manufacturer, Matcher, MatcherDef, Year};

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Accelerometer {
    pub chip_type: Option<String>,
    pub manufacturer: Option<Manufacturer>,
    pub year: Option<Year>,
    pub week: Option<u8>,
}

/// ```
/// # use gbhwdb_backend::parser::parse_accelerometer;
/// assert!(parse_accelerometer("2738109451 0028 ADXL202JQC").is_some());
/// ```
fn analog_adxl202jqc() -> MatcherDef<Accelerometer> {
    MatcherDef(
        r#"^[0-9]{10}\ ([0-9]{2})([0-9]{2})\ ADXL202JQC?$"#,
        move |c| {
            Ok(Accelerometer {
                chip_type: Some("ADXL202JQC".to_owned()),
                manufacturer: Some(Manufacturer::Analog),
                year: Some(year2(&c[1])?),
                week: Some(week2(&c[2])?),
            })
        },
    )
}

pub fn parse_accelerometer(text: &str) -> Option<Accelerometer> {
    lazy_static! {
        static ref MATCHER: Matcher<Accelerometer> = analog_adxl202jqc().into();
    }
    MATCHER.apply(text)
}
<commit_msg>Make ADXL202JQC parser stricter<commit_after>use lazy_static::lazy_static;

use super::{week2, year2, Manufacturer, Matcher, MatcherDef, Year};

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Accelerometer {
    pub chip_type: Option<String>,
    pub manufacturer: Option<Manufacturer>,
    pub year: Option<Year>,
    pub week: Option<u8>,
}

/// ```
/// # use gbhwdb_backend::parser::parse_accelerometer;
/// assert!(parse_accelerometer("2738109451 0028 ADXL202JQC").is_some());
/// ```
fn analog_adxl202jqc() -> MatcherDef<Accelerometer> {
    MatcherDef(
        r#"^[0-9]{10}\ ([0-9]{2})([0-9]{2})\ ADXL202JQC$"#,
        move |c| {
            Ok(Accelerometer {
                chip_type: Some("ADXL202JQC".to_owned()),
                manufacturer: Some(Manufacturer::Analog),
                year: Some(year2(&c[1])?),
                week: Some(week2(&c[2])?),
            })
        },
    )
}

pub fn parse_accelerometer(text: &str) -> Option<Accelerometer> {
    lazy_static! {
        static ref MATCHER: Matcher<Accelerometer> = analog_adxl202jqc().into();
    }
    MATCHER.apply(text)
}
<|endoftext|>