ocl/standard/
event.rs

1//! An OpenCL event.
2//!
3//
4// ### Notes
5//
6// * `EventArray` (a stack allocated event list with a maximum length of 8,
7//   akin to `RawEventArray`) is incomplete (TODO: Complete it).
8// * It's not yet clear whether or not to keep EventArray and EventList
9//   separate or to combine them into a smart-list that might be either one
10//   depending on the circumstances.
11// * It would be nice to have a "master" list type but it doesn't look like
12//   that's particularly feasable (although ClWaitListPtrEnum basically serves
13//   that role as long as lifetimes aren't an issue).
14//
15
16extern crate nodrop;
17
18use self::nodrop::NoDrop;
19use crate::core::{
20    self, ClContextPtr, ClEventPtrRef, ClNullEventPtr, ClWaitListPtr,
21    CommandQueue as CommandQueueCore, Event as EventCore, EventInfo, EventInfoResult,
22    ProfilingInfo, ProfilingInfoResult,
23};
24use crate::error::{Error as OclError, Result as OclResult};
25use crate::ffi::cl_event;
26use crate::standard::{ClWaitListPtrEnum, Queue};
27#[cfg(not(feature = "async_block"))]
28use crate::standard::{_unpark_task, box_raw_void};
29#[cfg(not(feature = "async_block"))]
30use futures::task;
31use futures::{Async, Future, Poll};
32use std::borrow::Borrow;
33use std::cell::Ref;
34use std::ops::{Deref, DerefMut};
35use std::{
36    fmt,
37    mem::{self, ManuallyDrop},
38    ptr,
39};
40
41const PRINT_DEBUG: bool = false;
42
43/// An event representing a command or user created event.
44///
45#[derive(Clone, Debug, Hash, PartialEq, Eq)]
46#[repr(C)]
47#[must_use = "futures do nothing unless polled"]
48pub struct Event(EventCore);
49
50impl Event {
51    /// Creates a new, empty (null) event which must be filled by a command,
52    /// associating the event with it.
53    pub fn empty() -> Event {
54        Event(EventCore::null())
55    }
56
57    /// Creates a new, empty event which must be filled by a newly initiated
58    /// command, associating the event with it.
59    pub fn user<C: ClContextPtr>(context: C) -> OclResult<Event> {
60        EventCore::user(context).map(Event).map_err(OclError::from)
61    }
62
63    /// Returns true if this event is 'empty' and has not yet been associated
64    /// with a command.
65    ///
66    #[inline]
67    pub fn is_empty(&self) -> bool {
68        self.0.is_null()
69    }
70
71    /// Sets a callback function to trigger upon completion of this event
72    /// which will unpark the current task.
73    ///
74    /// To be used within the context of a futures task.
75    ///
76    /// ## Panics
77    ///
78    /// This function will panic if a task is not currently being executed.
79    /// That is, this method can be dangerous to call outside of an
80    /// implementation of poll.
81    #[cfg(not(feature = "async_block"))]
82    pub fn set_unpark_callback(&self) -> OclResult<()> {
83        let task_ptr = box_raw_void(task::current());
84        unsafe {
85            self.set_callback(_unpark_task, task_ptr)
86                .map_err(OclError::from)
87        }
88    }
89
90    /// Registers a user event to have its status set to complete
91    /// (`CommandExecutionStatus::Complete`) immediately upon completion of
92    /// this event.
93    ///
94    /// ## Deadlocks
95    ///
96    /// Due to the nature of OpenCL queue implementations, care must be taken
97    /// when using this function. OpenCL queue deadlocks may occur.
98    ///
99    /// OpenCL queues generally use one thread per queue for the purposes of
100    /// callbacks, etc. As a rule of thumb, ensure that any OpenCL commands
101    /// preceding the causation/source event (`self`) are in a separate queue
102    /// from any commands with the dependent/target event (`user_event`).
103    ///
104    /// ## Safety
105    ///
106    /// The caller must ensure that `user_event` was created with
107    /// `Event::user()` and that it's status is
108    /// `CommandExecutionStatus::Submitted` (the default upon creation).
109    ///
110    #[cfg(not(feature = "async_block"))]
111    pub unsafe fn register_event_relay(&self, user_event: Event) -> OclResult<()> {
112        let unmap_event_ptr = user_event.into_raw();
113        self.set_callback(core::_complete_user_event, unmap_event_ptr)
114            .map_err(OclError::from)
115    }
116
117    /// Returns info about the event.
118    pub fn info(&self, info_kind: EventInfo) -> OclResult<EventInfoResult> {
119        core::get_event_info(&self.0, info_kind).map_err(OclError::from)
120    }
121
122    /// Returns info about the event.
123    pub fn profiling_info(&self, info_kind: ProfilingInfo) -> OclResult<ProfilingInfoResult> {
124        core::get_event_profiling_info(&self.0, info_kind).map_err(OclError::from)
125    }
126
127    /// Returns this event's associated command queue.
128    pub fn queue_core(&self) -> OclResult<CommandQueueCore> {
129        match self.info(EventInfo::CommandQueue)? {
130            EventInfoResult::CommandQueue(queue_core) => Ok(queue_core),
131            _ => unreachable!(),
132        }
133    }
134
135    /// Returns a reference to the core pointer wrapper, usable by functions in
136    /// the `core` module.
137    ///
138    #[inline]
139    pub fn as_core(&self) -> &EventCore {
140        &self.0
141    }
142
143    /// Consumes the `Event`, returning the wrapped `cl_event` pointer.
144    ///
145    /// To avoid a memory leak the pointer must be converted back to an `Event` using
146    /// [`Event::from_raw`][from_raw].
147    ///
148    /// [from_raw]: struct.Event.html#method.from_raw
149    ///
150    #[inline]
151    pub fn into_raw(self) -> cl_event {
152        self.0.into_raw()
153    }
154
155    /// Constructs an `Event` from a raw `cl_event` pointer.
156    ///
157    /// The raw pointer must have been previously returned by a call to a
158    /// [`Event::into_raw`][into_raw].
159    ///
160    /// [into_raw]: struct.Event.html#method.into_raw
161    #[inline]
162    pub unsafe fn from_raw(ptr: cl_event) -> Event {
163        EventCore::from_raw(ptr).into()
164    }
165
166    fn fmt_info(&self, f: &mut fmt::Formatter) -> fmt::Result {
167        f.debug_struct("Event")
168            .field("CommandQueue", &self.info(EventInfo::CommandQueue))
169            .field("CommandType", &self.info(EventInfo::CommandType))
170            .field("ReferenceCount", &self.info(EventInfo::ReferenceCount))
171            .field(
172                "CommandExecutionStatus",
173                &self.info(EventInfo::CommandExecutionStatus),
174            )
175            .field("Context", &self.info(EventInfo::Context))
176            .finish()
177    }
178
179    #[inline]
180    fn _count(&self) -> u32 {
181        if self.0.is_null() {
182            0
183        } else {
184            1
185        }
186    }
187}
188
189impl From<EventCore> for Event {
190    #[inline]
191    fn from(ev: EventCore) -> Event {
192        if ev.is_valid() {
193            Event(ev)
194        } else {
195            panic!("ocl::Event::from::<EventCore>: Invalid event.");
196        }
197    }
198}
199
200impl From<Event> for EventCore {
201    #[inline]
202    fn from(ev: Event) -> EventCore {
203        if ev.is_valid() {
204            ev.0
205        } else {
206            panic!("ocl::EventCore::from::<Event>: Invalid event.");
207        }
208    }
209}
210
211impl Default for Event {
212    fn default() -> Event {
213        Event::empty()
214    }
215}
216
217impl Deref for Event {
218    type Target = EventCore;
219
220    fn deref(&self) -> &EventCore {
221        &self.0
222    }
223}
224
225impl DerefMut for Event {
226    fn deref_mut(&mut self) -> &mut EventCore {
227        &mut self.0
228    }
229}
230
231impl AsRef<EventCore> for Event {
232    fn as_ref(&self) -> &EventCore {
233        &self.0
234    }
235}
236
237impl fmt::Display for Event {
238    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
239        self.fmt_info(f)
240    }
241}
242
243unsafe impl<'e> ClEventPtrRef<'e> for Event {
244    unsafe fn as_ptr_ref(&'e self) -> &'e cl_event {
245        self.0.as_ptr_ref()
246    }
247}
248
249unsafe impl<'a> ClNullEventPtr for &'a mut Event {
250    #[inline]
251    fn alloc_new(&mut self) -> *mut cl_event {
252        (&mut self.0).alloc_new()
253    }
254
255    #[inline]
256    unsafe fn clone_from<E: AsRef<EventCore>>(&mut self, ev: E) {
257        self.0.clone_from(ev.as_ref())
258    }
259}
260
261unsafe impl ClWaitListPtr for Event {
262    #[inline]
263    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
264        self.0.as_ptr_ptr()
265    }
266    #[inline]
267    fn count(&self) -> u32 {
268        self._count()
269    }
270}
271
272unsafe impl<'a> ClWaitListPtr for &'a Event {
273    #[inline]
274    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
275        self.0.as_ptr_ptr()
276    }
277    #[inline]
278    fn count(&self) -> u32 {
279        self._count()
280    }
281}
282
283impl Future for Event {
284    type Item = ();
285    type Error = OclError;
286
287    // Non-blocking, proper implementation.
288    //
289    // * NOTE: There is currently no check to ensure that only one callback is
290    //   created (is this ok?).
291    //   - TODO: Look into possible effects of unparking a task multiple times.
292    //
293    #[cfg(not(feature = "async_block"))]
294    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
295        debug_assert!(self.0.is_valid());
296
297        match self.is_complete() {
298            Ok(true) => Ok(Async::Ready(())),
299            Ok(false) => {
300                self.set_unpark_callback()?;
301                Ok(Async::NotReady)
302            }
303            Err(err) => Err(OclError::from(err)),
304        }
305    }
306
307    // Blocking implementation (yuk).
308    #[cfg(feature = "async_block")]
309    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
310        debug_assert!(self.0.is_valid());
311        self.wait_for()?;
312        Ok(Async::Ready(()))
313    }
314}
315
316/// Returns an empty, initialized (zeroed) event array.
317fn empty_event_array() -> NoDrop<[Event; 8]> {
318    NoDrop::new(Default::default())
319}
320
321/// Swaps an event with a new empty (null) event and returns it.
322fn take(event: &mut Event) -> Event {
323    let mut eold = Event::empty();
324    mem::swap(event, &mut eold);
325    eold
326}
327
328/// Polls events for `EventArray` and `EventList`
329fn poll_events(events: &[Event]) -> Poll<(), OclError> {
330    if PRINT_DEBUG {
331        println!(
332            "####### EventList/Array::poll: Polling Event list (thread: '{}')",
333            ::std::thread::current().name().unwrap_or("<unnamed>")
334        );
335    }
336
337    for event in events.iter() {
338        if cfg!(feature = "async_block") {
339            if PRINT_DEBUG {
340                println!(
341                    "####### EventList/Array::poll: waiting for for event: {:?} \
342                (thread: '{}')",
343                    event,
344                    ::std::thread::current().name().unwrap_or("<unnamed>")
345                );
346            }
347            event.wait_for()?;
348        } else {
349            if !event.is_complete()? {
350                #[cfg(not(feature = "async_block"))]
351                event.set_unpark_callback()?;
352                if PRINT_DEBUG {
353                    println!(
354                        "####### EventList/Array::poll: callback set for event: {:?} \
355                    (thread: '{}')",
356                        event,
357                        ::std::thread::current().name().unwrap_or("<unnamed>")
358                    );
359                }
360                return Ok(Async::NotReady);
361            } else {
362                if PRINT_DEBUG {
363                    println!(
364                        "####### EventList/Array::poll: event complete: {:?} \
365                    (thread: '{}')",
366                        event,
367                        ::std::thread::current().name().unwrap_or("<unnamed>")
368                    );
369                }
370            }
371        }
372    }
373
374    // let res = future::join_all(self.events.clone()).poll().map(|res| res.map(|_| ()) );
375    if PRINT_DEBUG {
376        println!(
377            "####### EventList/Array::poll: All events complete (thread: '{}')",
378            ::std::thread::current().name().unwrap_or("<unnamed>")
379        );
380    }
381
382    Ok(Async::Ready(()))
383    // res
384}
385
386/// A list of events for coordinating enqueued commands.
387///
388/// Events contain status information about the command that
389/// created them. Used to coordinate the activity of multiple commands with
390/// more fine-grained control than the queue alone.
391///
392/// For access to individual events use `get_clone` or `last_clone`.
393///
394//
395// * [FIXME] TODO: impl Index.
396// #[derive(Debug)]
397//
398// * [NOTE]: Consider replacing with
399//   `https://github.com/servo/rust-smallvec` instead.
400//
401pub struct EventArray {
402    array: NoDrop<[Event; 8]>,
403    len: usize,
404}
405
406impl EventArray {
407    /// Returns a new, empty, `EventArray`.
408    pub fn new() -> EventArray {
409        EventArray {
410            array: empty_event_array(),
411            len: 0,
412        }
413    }
414
415    /// Pushes a new event into the list.
416    pub fn push<E: Into<Event>>(&mut self, event: E) -> Result<(), Event> {
417        if (self.len) < self.array.len() {
418            let event = event.into();
419            debug_assert!(self.array[self.len].is_empty());
420            self.array[self.len] = event;
421            self.len += 1;
422            Ok(())
423        } else {
424            Err(event.into())
425        }
426    }
427
428    /// Removes the last event from the list and returns it.
429    pub fn pop(&mut self) -> Option<Event> {
430        if self.len > 0 {
431            self.len -= 1;
432            Some(take(&mut self.array[self.len]))
433        } else {
434            None
435        }
436    }
437
438    /// Removes an event from the list and returns it, swapping the last element into its place.
439    pub fn swap_remove(&mut self, idx: usize) -> Event {
440        assert!(idx < self.len);
441        let old = take(&mut self.array[idx]);
442        let src_ptr = &mut self.array[self.len - 1] as *mut Event;
443        let dst_ptr = &mut self.array[idx] as *mut Event;
444        unsafe {
445            ptr::swap(src_ptr, dst_ptr);
446        }
447        self.len -= 1;
448        old
449    }
450
451    /// Removes an event from the list and returns it, shifting elements after it to the left.
452    ///
453    /// [MAY DEPRICATE]: Prefer `::swap_remove`, this function is really unnecessary.
454    pub fn remove(&mut self, idx: usize) -> Event {
455        assert!(idx < self.len);
456        let old = take(&mut self.array[idx]);
457
458        // Shift everything after `idx` to the left:
459        unsafe {
460            let ptr = self.array.as_mut_ptr().add(idx);
461            ptr::copy(ptr.offset(1), ptr, self.len - idx - 1);
462        }
463        self.len -= 1;
464        old
465    }
466
467    /// Clears all events from the list whether or not they have completed.
468    ///
469    /// Forwards any errors related to releasing events.
470    ///
471    #[inline]
472    pub fn clear(&mut self) {
473        for ev in &mut self.array[..self.len] {
474            let _ = take(ev);
475        }
476        self.len = 0;
477    }
478
479    /// Clears events which have already completed.
480    pub fn clear_completed(&mut self) -> OclResult<()> {
481        let mut new_len = 0;
482
483        for idx in 0..self.len {
484            if self.array[idx].is_complete()? {
485                let _ = take(&mut self.array[idx]);
486            } else {
487                let dst_ptr = &mut self.array[new_len] as *mut Event;
488                unsafe {
489                    ptr::swap(&mut self.array[idx], dst_ptr);
490                }
491                new_len += 1;
492            }
493        }
494
495        self.len = new_len;
496        Ok(())
497    }
498
499    /// Blocks the host thread until all events in this list are complete.
500    pub fn wait_for(&self) -> OclResult<()> {
501        for ev in &self.array[..self.len] {
502            ev.wait_for()?;
503        }
504        Ok(())
505    }
506
507    /// Enqueue a marker event representing the completion of each and every
508    /// event in this list.
509    pub fn enqueue_marker(&self, queue: &Queue) -> OclResult<Event> {
510        if self.array.is_empty() {
511            return Err("EventArray::enqueue_marker: List empty.".into());
512        }
513        queue.enqueue_marker(Some(self)).map_err(OclError::from)
514    }
515
516    /// The number of events in this list.
517    #[inline]
518    pub fn len(&self) -> usize {
519        self.len
520    }
521
522    /// Returns a slice of events in the list.
523    #[inline]
524    pub fn as_slice(&self) -> &[Event] {
525        &self.array[..self.len]
526    }
527
528    /// Returns a mutable slice of events in the list.
529    #[inline]
530    pub fn as_mut_slice(&mut self) -> &mut [Event] {
531        &mut self.array[..self.len]
532    }
533
534    #[inline]
535    fn _alloc_new(&mut self) -> Result<*mut cl_event, &'static str> {
536        match self.push(Event::empty()) {
537            Ok(_) => Ok((&mut self.array[self.len - 1]) as *mut _ as *mut cl_event),
538            Err(_) => Err(
539                "EventArray::_alloc_new: Error attempting to add a new event \
540                to the event list: this list is full",
541            ),
542        }
543    }
544
545    #[inline]
546    unsafe fn _as_ptr_ptr(&self) -> *const cl_event {
547        if self.len > 0 {
548            &self.array[0] as *const _ as *const cl_event
549        } else {
550            ptr::null()
551        }
552    }
553
554    #[inline]
555    fn _count(&self) -> u32 {
556        self.len as u32
557    }
558}
559
560// Due to a fix to coherence rules
561// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
562// this for each event type.
563macro_rules! from_event_into_event_array(
564    ($e:ty) => (
565        impl<'a> From<$e> for EventArray {
566            fn from(event: $e) -> EventArray {
567                let mut array = empty_event_array();
568                array[0] = event.into();
569
570                EventArray {
571                    array: array,
572                    len: 1,
573                }
574            }
575        }
576    )
577);
578from_event_into_event_array!(EventCore);
579from_event_into_event_array!(Event);
580
581impl<'a, E> From<&'a E> for EventArray
582where
583    E: Into<Event> + Clone,
584{
585    #[inline]
586    fn from(event: &E) -> EventArray {
587        Self::from(event.clone().into())
588    }
589}
590
591impl<'a, E> From<&'a [E]> for EventArray
592where
593    E: Into<Event> + Clone,
594{
595    fn from(events: &[E]) -> EventArray {
596        let mut array = empty_event_array();
597
598        for (idx, event) in events.iter().enumerate() {
599            array[idx] = event.clone().into();
600        }
601
602        EventArray {
603            array,
604            len: events.len(),
605        }
606    }
607}
608
609impl Deref for EventArray {
610    type Target = [Event];
611
612    #[inline]
613    fn deref(&self) -> &[Event] {
614        self.as_slice()
615    }
616}
617
618impl DerefMut for EventArray {
619    #[inline]
620    fn deref_mut(&mut self) -> &mut [Event] {
621        self.as_mut_slice()
622    }
623}
624
625impl Clone for EventArray {
626    fn clone(&self) -> EventArray {
627        let mut new_a = empty_event_array();
628        for i in 0..self.len {
629            new_a[i] = self.array[i].clone();
630        }
631        EventArray {
632            array: new_a,
633            len: self.len,
634        }
635    }
636}
637
638impl Drop for EventArray {
639    fn drop(&mut self) {
640        // ptr::drop_in_place(self.as_mut_slice());
641        self.clear();
642
643        for idx in 0..self.array.len() {
644            debug_assert!(self.array[idx].is_empty());
645        }
646    }
647}
648
649impl fmt::Debug for EventArray {
650    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
651        write!(
652            f,
653            "EventArray {{ array: {:?}, len: {} }}",
654            &self.array[..],
655            self.len
656        )
657    }
658}
659
660impl Future for EventArray {
661    type Item = ();
662    type Error = OclError;
663
664    /// Polls each event from this list.
665    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
666        poll_events(self.as_slice())
667    }
668}
669
670unsafe impl<'a> ClNullEventPtr for &'a mut EventArray {
671    #[inline]
672    fn alloc_new(&mut self) -> *mut cl_event {
673        self._alloc_new()
674            .expect("<EventArray as ClNullEventPtr>::alloc_new")
675    }
676
677    #[inline]
678    unsafe fn clone_from<E: AsRef<EventCore>>(&mut self, ev: E) {
679        assert!(ev.as_ref().is_valid());
680        *self
681            ._alloc_new()
682            .expect("<EventArray as ClNullEventPtr>::clone_from") = ev.as_ref().clone().into_raw()
683    }
684}
685
686unsafe impl ClWaitListPtr for EventArray {
687    #[inline]
688    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
689        self._as_ptr_ptr()
690    }
691    #[inline]
692    fn count(&self) -> u32 {
693        self._count()
694    }
695}
696
697unsafe impl<'a> ClWaitListPtr for &'a EventArray {
698    #[inline]
699    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
700        self._as_ptr_ptr()
701    }
702    #[inline]
703    fn count(&self) -> u32 {
704        self._count()
705    }
706}
707
708/// The guts of an EventList.
709#[derive(Debug, Clone)]
710enum Inner {
711    Array(EventArray),
712    Vec(Vec<Event>),
713}
714
715/// A list of events for coordinating enqueued commands.
716///
717/// Events contain status information about the command that
718/// created them. Used to coordinate the activity of multiple commands with
719/// more fine-grained control than the queue alone.
720///
721/// For access to individual events use `get_clone` or `last_clone`.
722///
723/// `EventList` is a dynamically allocated list. It will be (internally) stack
724/// allocated (as an `[Event; 8]`) until it reaches a length of 9 at which
725/// time it will become heap-allocated (a `Vec<Event>`).
726///
727/// Converting back from heap to stack allocation is currently not
728/// implemented.
729///
730// * [FIXME] TODO: impl Index.
731//
732// * [NOTE]: Consider implementing using
733//   `https://github.com/servo/rust-smallvec` instead.
734//
735#[derive(Debug, Clone)]
736pub struct EventList {
737    inner: Inner,
738}
739
740impl EventList {
741    /// Returns a new, empty, stack-allocated `EventList`.
742    #[inline]
743    pub fn new() -> EventList {
744        EventList {
745            inner: Inner::Array(EventArray::new()),
746        }
747    }
748
749    /// Returns a new, empty, EventList` with an initial capacity of `cap`.
750    ///
751    /// If `cap` is greater than 8, the event list will be heap-allocated.
752    #[inline]
753    pub fn with_capacity(cap: usize) -> EventList {
754        if cap <= 8 {
755            EventList {
756                inner: Inner::Array(EventArray::new()),
757            }
758        } else {
759            EventList {
760                inner: Inner::Vec(Vec::with_capacity(cap)),
761            }
762        }
763    }
764
765    /// Converts the contained list from a stack allocated to a heap allocated
766    /// array [or vice-versa].
767    ///
768    /// FIXME: Implement conversion from Vec -> array.
769    fn convert(&mut self) {
770        let new_inner: Inner;
771
772        match self.inner {
773            Inner::Array(ref a) => {
774                let vec = a.as_slice().to_owned();
775                new_inner = Inner::Vec(vec);
776            }
777            Inner::Vec(ref _v) => unimplemented!(),
778        }
779
780        self.inner = new_inner;
781    }
782
783    /// Adds an event to the list.
784    //
785    // TODO: Clean this up. There must be a simpler way to do this.
786    #[inline]
787    pub fn push<E: Into<Event>>(&mut self, event: E) {
788        let mut event: Option<Event> = Some(event.into());
789
790        match self.inner {
791            Inner::Array(ref mut a) => {
792                if let Some(ev) = event {
793                    match a.push(ev) {
794                        Ok(_) => return,
795                        Err(ev) => event = Some(ev),
796                    }
797                }
798            }
799            Inner::Vec(ref mut v) => {
800                if let Some(ev) = event {
801                    v.push(ev);
802                }
803                return;
804            }
805        }
806
807        if let Some(ev) = event {
808            self.convert();
809            self.push(ev);
810        }
811    }
812
813    /// Removes the last event from the list and returns it.
814    #[inline]
815    pub fn pop(&mut self) -> Option<Event> {
816        match self.inner {
817            Inner::Array(ref mut a) => a.pop(),
818            Inner::Vec(ref mut v) => v.pop(),
819        }
820    }
821
822    /// Clears all events from the list whether or not they have completed.
823    ///
824    /// Forwards any errors related to releasing events.
825    ///
826    #[inline]
827    pub fn clear(&mut self) {
828        match self.inner {
829            Inner::Array(ref mut a) => a.clear(),
830            Inner::Vec(ref mut v) => v.clear(),
831        }
832    }
833
834    /// Clears events which have completed.
835    pub fn clear_completed(&mut self) -> OclResult<()> {
836        match self.inner {
837            Inner::Array(ref mut a) => a.clear_completed(),
838            Inner::Vec(ref mut v) => {
839                // * TODO: Reimplement optimized version using
840                //   `util::vec_remove_rebuild` (from old `EventListCore`).
841                let mut events = Vec::with_capacity(v.capacity());
842                mem::swap(&mut events, v);
843                for event in events {
844                    if !event.is_complete()? {
845                        v.push(event);
846                    }
847                }
848                Ok(())
849            }
850        }
851    }
852
853    /// Blocks the host thread until all events in this list are complete.
854    pub fn wait_for(&self) -> OclResult<()> {
855        match self.inner {
856            Inner::Array(ref a) => a.wait_for(),
857            Inner::Vec(ref v) => {
858                for event in v.iter() {
859                    event.wait_for()?;
860                }
861                Ok(())
862            }
863        }
864    }
865
866    /// Enqueue a marker event representing the completion of each and every
867    /// event in this list.
868    ///
869    /// ### Platform Compatibility
870    ///
871    /// Some device/platform combinations (particularly older Intel CPUs on
872    /// Intel platform drivers) may have intermittent issues waiting on
873    /// markers when multiple threads are in use. This is rare and can be
874    /// circumvented by using AMD platform drivers instead. Please file an
875    /// issue immediately if you run into problems on your platform so that we
876    /// may make note of it here in the documentation.
877    ///
878    pub fn enqueue_marker(&self, queue: &Queue) -> OclResult<Event> {
879        match self.inner {
880            Inner::Array(ref a) => a.enqueue_marker(queue).map_err(OclError::from),
881            Inner::Vec(ref v) => {
882                if v.is_empty() {
883                    return Err("EventList::enqueue_marker: List empty.".into());
884                }
885                queue.enqueue_marker(Some(self)).map_err(OclError::from)
886            }
887        }
888    }
889
890    /// Returns a slice of the contained events.
891    #[inline]
892    pub fn as_slice(&self) -> &[Event] {
893        match self.inner {
894            Inner::Array(ref a) => a.as_slice(),
895            Inner::Vec(ref v) => v.as_slice(),
896        }
897    }
898
899    /// Returns a mutable slice of the contained events.
900    #[inline]
901    pub fn as_mut_slice(&mut self) -> &mut [Event] {
902        match self.inner {
903            Inner::Array(ref mut a) => a.as_mut_slice(),
904            Inner::Vec(ref mut v) => v.as_mut_slice(),
905        }
906    }
907
908    #[inline]
909    fn _alloc_new(&mut self) -> *mut cl_event {
910        match self.inner {
911            Inner::Array(ref mut a) => match a._alloc_new() {
912                Ok(ptr) => return ptr,
913                Err(_) => (),
914            },
915            Inner::Vec(ref mut v) => {
916                v.push(Event::empty());
917                return v.last_mut().unwrap() as *mut _ as *mut cl_event;
918            }
919        }
920
921        self.convert();
922        self._alloc_new()
923    }
924
925    #[inline]
926    unsafe fn _as_ptr_ptr(&self) -> *const cl_event {
927        match self.inner {
928            Inner::Array(ref a) => a._as_ptr_ptr(),
929            Inner::Vec(ref v) => match v.first() {
930                Some(ev) => ev as *const _ as *const cl_event,
931                None => ptr::null(),
932            },
933        }
934    }
935
936    #[inline]
937    fn _count(&self) -> u32 {
938        match self.inner {
939            Inner::Array(ref a) => a._count(),
940            Inner::Vec(ref v) => v.len() as u32,
941        }
942    }
943}
944
945// Due to a fix to coherence rules
946// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
947// this for each event type.
948macro_rules! from_event_into_event_list(
949    ($e:ty) => (
950        impl<'a> From<$e> for EventList {
951            #[inline]
952            fn from(event: $e) -> EventList {
953                EventList { inner: Inner::Array(EventArray::from(event)) }
954            }
955        }
956    )
957);
958from_event_into_event_list!(EventCore);
959from_event_into_event_list!(Event);
960
961impl<'a, E> From<&'a E> for EventList
962where
963    E: Into<Event> + Clone,
964{
965    #[inline]
966    fn from(event: &E) -> EventList {
967        EventList {
968            inner: Inner::Array(EventArray::from(event)),
969        }
970    }
971}
972
973impl<'a> From<Vec<Event>> for EventList {
974    #[inline]
975    fn from(events: Vec<Event>) -> EventList {
976        EventList {
977            inner: Inner::Vec(events),
978        }
979    }
980}
981
982// Due to a fix to coherence rules
983// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
984// this for each event type.
985macro_rules! from_event_option_ref_into_event_list(
986    ($e:ty) => (
987        impl<'a> From<&'a Option<$e>> for EventList {
988            fn from(event: &Option<$e>) -> EventList {
989                let mut el = EventList::new();
990                if let Some(ref e) = *event { el.push::<Event>(e.clone().into()) }
991                el
992            }
993        }
994    )
995);
996from_event_option_ref_into_event_list!(EventCore);
997from_event_option_ref_into_event_list!(Event);
998
999impl<'a, 'b, E> From<Option<&'b E>> for EventList
1000where
1001    'b: 'a,
1002    E: Into<Event> + Clone,
1003{
1004    fn from(event: Option<&E>) -> EventList {
1005        let mut el = EventList::new();
1006        if let Some(e) = event {
1007            el.push(e.clone().into())
1008        }
1009        el
1010    }
1011}
1012
1013impl<'a, 'b, E> From<&'a Option<&'b E>> for EventList
1014where
1015    'b: 'a,
1016    E: Into<Event> + Clone,
1017{
1018    fn from(event: &Option<&E>) -> EventList {
1019        let mut el = EventList::new();
1020        if let Some(e) = *event {
1021            el.push(e.clone().into())
1022        }
1023        el
1024    }
1025}
1026
1027impl<'a, E> From<&'a [E]> for EventList
1028where
1029    E: Into<Event> + Clone,
1030{
1031    fn from(events: &[E]) -> EventList {
1032        if events.len() <= 8 {
1033            EventList {
1034                inner: Inner::Array(EventArray::from(events)),
1035            }
1036        } else {
1037            EventList {
1038                inner: Inner::Vec(events.iter().map(|e| e.clone().into()).collect()),
1039            }
1040        }
1041    }
1042}
1043
1044// Due to a fix to coherence rules
1045// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
1046// this for each event type.
1047macro_rules! from_event_option_into_event_list(
1048    ($e:ty) => (
1049        impl<'a> From<&'a [Option<$e>]> for EventList {
1050            fn from(events: &[Option<$e>]) -> EventList {
1051                let mut el = EventList::with_capacity(events.len());
1052                for event in events {
1053                    if let Some(ref e) = *event { el.push::<Event>(e.clone().into()) }
1054                }
1055                el
1056            }
1057        }
1058    )
1059);
1060from_event_option_into_event_list!(EventCore);
1061from_event_option_into_event_list!(Event);
1062
1063impl<'a, 'b, E> From<&'a [Option<&'b E>]> for EventList
1064where
1065    'b: 'a,
1066    E: Into<Event> + Clone,
1067{
1068    fn from(events: &[Option<&E>]) -> EventList {
1069        let mut el = EventList::with_capacity(events.len());
1070        for event in events {
1071            if let Some(e) = *event {
1072                el.push(e.clone().into())
1073            }
1074        }
1075        el
1076    }
1077}
1078
1079// Due to a fix to coherence rules
1080// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
1081// this for each event type.
1082macro_rules! from_event_option_slice_into_event_list(
1083    ($e:ty) => (
1084        impl<'a, 'b> From<&'a [&'b Option<$e>]> for EventList where 'b: 'a {
1085            fn from(events: &[&Option<$e>]) -> EventList {
1086                let mut el = EventList::with_capacity(events.len());
1087                for event in events {
1088                    if let Some(ref e) = **event { el.push::<Event>(e.clone().into()) }
1089                }
1090                el
1091            }
1092        }
1093    )
1094);
1095from_event_option_slice_into_event_list!(EventCore);
1096from_event_option_slice_into_event_list!(Event);
1097
1098impl<'a, 'b, 'c, E> From<&'a [&'b Option<&'c E>]> for EventList
1099where
1100    'c: 'b,
1101    'b: 'a,
1102    E: Into<Event> + Clone,
1103{
1104    fn from(events: &[&Option<&E>]) -> EventList {
1105        let mut el = EventList::with_capacity(events.len());
1106
1107        for event in events {
1108            if let Some(e) = **event {
1109                el.push(e.clone().into())
1110            }
1111        }
1112        el
1113    }
1114}
1115
1116// Due to a fix to coherence rules
1117// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
1118// this for each event type.
1119macro_rules! from_event_option_array_into_event_list(
1120    ($e:ty, $len:expr) => (
1121        impl<'e> From<[Option<$e>; $len]> for EventList {
1122            fn from(events: [Option<$e>; $len]) -> EventList {
1123                let mut el = ManuallyDrop::new(
1124                    EventList::with_capacity(events.len())
1125                );
1126
1127                for idx in 0..events.len() {
1128                    let event_opt = unsafe {
1129                        ptr::read(events.get_unchecked(idx))
1130                    };
1131
1132                    if let Some(event) = event_opt {
1133                        // Use `ManuallyDrop` to guard against
1134                        // potential panic within `into()`.
1135                        let event = ManuallyDrop::into_inner(
1136                            ManuallyDrop::new(event)
1137                            .into()
1138                        );
1139                        el.push(event);
1140                    }
1141                }
1142                mem::forget(events);
1143
1144                ManuallyDrop::into_inner(el)
1145            }
1146        }
1147    )
1148);
1149
1150// Due to a fix to coherence rules
1151// (https://github.com/rust-lang/rust/pull/46192) we must manually implement
1152// this for each event type.
1153macro_rules! from_event_option_ref_array_into_event_list(
1154    ($e:ty, $len:expr) => (
1155        impl<'e, 'f> From<[&'f Option<$e>; $len]> for EventList where 'e: 'f {
1156            fn from(events: [&'f Option<$e>; $len]) -> EventList {
1157                let mut el = EventList::with_capacity(events.len());
1158                for event_opt in &events {
1159                    if let Some(event) = *event_opt {
1160                        el.push(event.clone());
1161                    }
1162                }
1163                el
1164            }
1165        }
1166    )
1167);
1168
1169macro_rules! impl_event_list_from_arrays {
1170    ($( $len:expr ),*) => ($(
1171        impl<'e, E> From<[E; $len]> for EventList where E: Into<Event> {
1172            fn from(events: [E; $len]) -> EventList {
1173                let mut el = ManuallyDrop::new(
1174                    EventList::with_capacity(events.len())
1175                );
1176
1177                for idx in 0..events.len() {
1178                    // User `ManuallyDrop` to guard against potential panic within `into()`.
1179                    let event = ManuallyDrop::into_inner(
1180                        ManuallyDrop::new(
1181                            unsafe {
1182                                ptr::read(events.get_unchecked(idx))
1183                            }
1184                        )
1185                        .into()
1186                    );
1187                    el.push(event);
1188                }
1189                // Ownership has been unsafely transfered to the new event
1190                // list without modifying the event reference count. Not
1191                // forgetting the source array would cause a double drop.
1192                mem::forget(events);
1193
1194                ManuallyDrop::into_inner(el)
1195            }
1196        }
1197
1198        from_event_option_array_into_event_list!(EventCore, $len);
1199        from_event_option_array_into_event_list!(Event, $len);
1200
1201        impl<'e, E> From<[Option<&'e E>; $len]> for EventList where E: Into<Event> + Clone {
1202            fn from(events: [Option<&E>; $len]) -> EventList {
1203                let mut el = EventList::with_capacity(events.len());
1204                for event_opt in &events {
1205                    if let Some(event) = event_opt.cloned() {
1206                        el.push(event);
1207                    }
1208                }
1209                el
1210            }
1211        }
1212
1213        from_event_option_ref_array_into_event_list!(EventCore, $len);
1214        from_event_option_ref_array_into_event_list!(Event, $len);
1215
1216        impl<'e, 'f, E> From<[&'f Option<&'e E>; $len]> for EventList where 'e: 'f, E: Into<Event> + Clone {
1217            fn from(events: [&'f Option<&'e E>; $len]) -> EventList {
1218                let mut el = EventList::with_capacity(events.len());
1219                for event_opt in &events {
1220                    if let Some(event) = event_opt.cloned() {
1221                        el.push(event);
1222                    }
1223                }
1224                el
1225            }
1226        }
1227    )*);
1228}
1229
1230impl_event_list_from_arrays!(1, 2, 3, 4, 5, 6, 7, 8);
1231
1232impl<'a> From<&'a [cl_event]> for EventList {
1233    fn from(raw_events: &[cl_event]) -> EventList {
1234        let mut event_list = EventList::new();
1235        for &ptr in raw_events {
1236            let event_core = unsafe {
1237                EventCore::from_raw_copied_ptr(ptr)
1238                    .expect("EventList::from: Error converting from raw 'cl_event'")
1239            };
1240            event_list.push(event_core);
1241        }
1242        event_list
1243    }
1244}
1245
1246impl<'a> From<EventArray> for EventList {
1247    #[inline]
1248    fn from(events: EventArray) -> EventList {
1249        EventList {
1250            inner: Inner::Array(events),
1251        }
1252    }
1253}
1254
1255impl<'a> From<RawEventArray> for EventList {
1256    #[inline]
1257    fn from(raw_events: RawEventArray) -> EventList {
1258        EventList::from(raw_events.as_slice())
1259    }
1260}
1261
1262impl<'a> From<Box<dyn ClWaitListPtr>> for EventList {
1263    fn from(trait_obj: Box<dyn ClWaitListPtr>) -> EventList {
1264        let raw_slice = unsafe {
1265            ::std::slice::from_raw_parts(trait_obj.as_ptr_ptr(), trait_obj.count() as usize)
1266        };
1267
1268        Self::from(raw_slice)
1269    }
1270}
1271
1272impl<'a> From<&'a Box<dyn ClWaitListPtr>> for EventList {
1273    fn from(trait_obj: &Box<dyn ClWaitListPtr>) -> EventList {
1274        let raw_slice = unsafe {
1275            ::std::slice::from_raw_parts(trait_obj.as_ptr_ptr(), trait_obj.count() as usize)
1276        };
1277
1278        Self::from(raw_slice)
1279    }
1280}
1281
1282impl<'a> From<Ref<'a, dyn ClWaitListPtr>> for EventList {
1283    fn from(trait_obj: Ref<'a, dyn ClWaitListPtr>) -> EventList {
1284        let raw_slice = unsafe {
1285            ::std::slice::from_raw_parts(trait_obj.as_ptr_ptr(), trait_obj.count() as usize)
1286        };
1287
1288        Self::from(raw_slice)
1289    }
1290}
1291
1292impl<'a> From<ClWaitListPtrEnum<'a>> for EventList {
1293    /// Returns an `EventList` containing owned copies of each element in
1294    /// this `ClWaitListPtrEnum`.
1295    fn from(wlpe: ClWaitListPtrEnum<'a>) -> EventList {
1296        match wlpe {
1297            ClWaitListPtrEnum::Null => EventList::with_capacity(0),
1298            ClWaitListPtrEnum::RawEventArray(e) => e.as_slice().into(),
1299            ClWaitListPtrEnum::EventCoreOwned(e) => EventList::from(vec![e.into()]),
1300            ClWaitListPtrEnum::EventOwned(e) => EventList::from(vec![e]),
1301            ClWaitListPtrEnum::EventCore(e) => EventList::from(vec![e.clone().into()]),
1302            ClWaitListPtrEnum::Event(e) => EventList::from(vec![e.clone().into()]),
1303            ClWaitListPtrEnum::EventList(e) => e.clone(),
1304            ClWaitListPtrEnum::EventSlice(e) => EventList::from(e),
1305            ClWaitListPtrEnum::EventPtrSlice(e) => EventList::from(e),
1306            ClWaitListPtrEnum::RefEventList(e) => (*e).clone(),
1307            ClWaitListPtrEnum::RefTraitObj(e) => e.into(),
1308            ClWaitListPtrEnum::BoxTraitObj(e) => e.into(),
1309        }
1310    }
1311}
1312
1313impl Deref for EventList {
1314    type Target = [Event];
1315
1316    #[inline]
1317    fn deref(&self) -> &[Event] {
1318        self.as_slice()
1319    }
1320}
1321
1322impl DerefMut for EventList {
1323    #[inline]
1324    fn deref_mut(&mut self) -> &mut [Event] {
1325        self.as_mut_slice()
1326    }
1327}
1328
1329impl IntoIterator for EventList {
1330    type Item = Event;
1331    type IntoIter = ::std::vec::IntoIter<Event>;
1332
1333    // * TODO: Currently converts a contained array to a vec. Will need
1334    //   something better eventually (perhaps wait for impl Trait to
1335    //   stabilize).
1336    #[inline]
1337    fn into_iter(self) -> Self::IntoIter {
1338        match self.inner {
1339            Inner::Array(a) => {
1340                let mut el = EventList {
1341                    inner: Inner::Array(a),
1342                };
1343                el.convert();
1344                el.into_iter()
1345            }
1346            Inner::Vec(v) => v.into_iter(),
1347        }
1348    }
1349}
1350
1351impl Future for EventList {
1352    type Item = ();
1353    type Error = OclError;
1354
1355    /// Polls each event from this list.
1356    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
1357        poll_events(self.as_slice())
1358    }
1359}
1360
1361unsafe impl<'a> ClNullEventPtr for &'a mut EventList {
1362    #[inline]
1363    fn alloc_new(&mut self) -> *mut cl_event {
1364        self._alloc_new()
1365    }
1366
1367    #[inline]
1368    unsafe fn clone_from<E: AsRef<EventCore>>(&mut self, ev: E) {
1369        assert!(ev.as_ref().is_valid());
1370        *self._alloc_new() = ev.as_ref().clone().into_raw()
1371    }
1372}
1373
1374unsafe impl ClWaitListPtr for EventList {
1375    #[inline]
1376    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
1377        self._as_ptr_ptr()
1378    }
1379    #[inline]
1380    fn count(&self) -> u32 {
1381        self._count()
1382    }
1383}
1384
1385unsafe impl<'a> ClWaitListPtr for &'a EventList {
1386    #[inline]
1387    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
1388        self._as_ptr_ptr()
1389    }
1390    #[inline]
1391    fn count(&self) -> u32 {
1392        self._count()
1393    }
1394}
1395
1396/// A stack allocated array of `cl_event` pointers with a maximum length of 8.
1397///
1398/// Do not store this list beyond the enqueue call(s) with which this list is
1399/// first used. Use `EventList` or `EventArray` for a persistent list.
1400///
1401//
1402// * [NOTE]: Consider implementing using
1403//   `https://github.com/servo/rust-smallvec` instead.
1404//
1405#[derive(Debug, Clone)]
1406pub struct RawEventArray {
1407    list: [cl_event; 8],
1408    len: usize,
1409}
1410
1411impl RawEventArray {
1412    pub unsafe fn null() -> RawEventArray {
1413        RawEventArray {
1414            list: [0 as cl_event; 8],
1415            len: 0,
1416        }
1417    }
1418
1419    #[inline]
1420    pub fn push<E>(&mut self, e: E)
1421    where
1422        E: AsRef<EventCore>,
1423    {
1424        if (self.len) < self.list.len() {
1425            self.list[self.len] = unsafe { *(e.as_ref().as_ptr_ref()) };
1426            self.len += 1;
1427        } else {
1428            panic!("RawEventArray::push: List is full.");
1429        }
1430    }
1431
1432    #[inline]
1433    unsafe fn _as_ptr_ptr(&self) -> *const cl_event {
1434        if self.len > 0 {
1435            &self.list as *const _ as *const cl_event
1436        } else {
1437            ptr::null()
1438        }
1439    }
1440
1441    /// Enqueue a marker event representing the completion of each and every
1442    /// event in this list.
1443    pub fn to_marker(&self, queue: &Queue) -> OclResult<Option<Event>> {
1444        if self.list.is_empty() {
1445            return Ok(None);
1446        }
1447        queue
1448            .enqueue_marker(Some(self))
1449            .map(Some)
1450            .map_err(OclError::from)
1451    }
1452
1453    /// Enqueue a marker event representing the completion of each and every
1454    /// event in this list.
1455    pub fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1456        self.to_marker(queue)
1457    }
1458
1459    /// Returns a slice of events in the list.
1460    pub fn as_slice(&self) -> &[cl_event] {
1461        &self.list[..self.len]
1462    }
1463
1464    /// Returns a mutable slice of events in the list.
1465    #[inline]
1466    pub fn as_mut_slice(&mut self) -> &mut [cl_event] {
1467        &mut self.list[..self.len]
1468    }
1469
1470    /// The number of events in this list.
1471    #[inline]
1472    pub fn len(&self) -> usize {
1473        self.len
1474    }
1475}
1476
1477impl<'e, E> From<&'e [E]> for RawEventArray
1478where
1479    E: Borrow<Event>,
1480{
1481    fn from(events: &[E]) -> RawEventArray {
1482        let mut list = unsafe { RawEventArray::null() };
1483        for e in events {
1484            list.push(e.borrow());
1485        }
1486        list
1487    }
1488}
1489
1490impl<'e, E> From<&'e [Option<E>]> for RawEventArray
1491where
1492    E: Borrow<Event>,
1493{
1494    fn from(events: &[Option<E>]) -> RawEventArray {
1495        let mut list = unsafe { RawEventArray::null() };
1496        for event in events {
1497            if let Some(ref e) = *event {
1498                list.push(e.borrow());
1499            }
1500        }
1501        list
1502    }
1503}
1504
1505impl<'e, 'f, E> From<&'e [&'f Option<E>]> for RawEventArray
1506where
1507    'e: 'f,
1508    E: Borrow<Event>,
1509{
1510    fn from(events: &[&Option<E>]) -> RawEventArray {
1511        let mut list = unsafe { RawEventArray::null() };
1512        for &event in events {
1513            if let Some(ref e) = *event {
1514                list.push(e.borrow());
1515            }
1516        }
1517        list
1518    }
1519}
1520
1521macro_rules! impl_raw_list_from_arrays {
1522    ($( $len:expr ),*) => ($(
1523        impl<'e, E> From<[E; $len]> for RawEventArray where E: Borrow<Event> {
1524            fn from(events: [E; $len]) -> RawEventArray {
1525                let mut list = unsafe { RawEventArray::null() };
1526                for e in &events {
1527                    list.push(e.borrow());
1528                }
1529                list
1530            }
1531        }
1532
1533        impl<'e, E> From<[Option<E>; $len]> for RawEventArray where E: Borrow<Event> {
1534            fn from(events: [Option<E>; $len]) -> RawEventArray {
1535                let mut list = unsafe { RawEventArray::null() };
1536                for event in &events {
1537                    if let Some(ref e) = *event {
1538                        list.push(e.borrow());
1539                    }
1540                }
1541                list
1542            }
1543        }
1544
1545        impl<'e, 'f, E> From<[&'f Option<E>; $len]> for RawEventArray where 'e: 'f, E: Borrow<Event> {
1546            fn from(events: [&'f Option<E>; $len]) -> RawEventArray {
1547                let mut list = unsafe { RawEventArray::null() };
1548                for &event in &events {
1549                    if let Some(ref e) = *event {
1550                        list.push(e.borrow());
1551                    }
1552                }
1553                list
1554            }
1555        }
1556    )*);
1557}
1558
1559impl_raw_list_from_arrays!(1, 2, 3, 4, 5, 6, 7, 8);
1560
1561unsafe impl ClWaitListPtr for RawEventArray {
1562    #[inline]
1563    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
1564        self._as_ptr_ptr()
1565    }
1566    #[inline]
1567    fn count(&self) -> u32 {
1568        self.len as u32
1569    }
1570}
1571
1572unsafe impl<'a> ClWaitListPtr for &'a RawEventArray {
1573    #[inline]
1574    unsafe fn as_ptr_ptr(&self) -> *const cl_event {
1575        self._as_ptr_ptr()
1576    }
1577    #[inline]
1578    fn count(&self) -> u32 {
1579        self.len as u32
1580    }
1581}
1582
1583/// Conversion to a 'marker' event.
1584pub trait IntoMarker {
1585    fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>>;
1586}
1587
1588impl<'s, 'e> IntoMarker for &'s [&'e Event]
1589where
1590    'e: 's,
1591{
1592    fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1593        RawEventArray::from(self).into_marker(queue)
1594    }
1595}
1596
1597impl<'s, 'e> IntoMarker for &'s [Option<&'e Event>]
1598where
1599    'e: 's,
1600{
1601    fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1602        RawEventArray::from(self).into_marker(queue)
1603    }
1604}
1605
1606impl<'s, 'o, 'e> IntoMarker for &'s [&'o Option<&'e Event>]
1607where
1608    'e: 's + 'o,
1609    'o: 's,
1610{
1611    fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1612        RawEventArray::from(self).into_marker(queue)
1613    }
1614}
1615
1616macro_rules! impl_marker_arrays {
1617    ($( $len:expr ),*) => ($(
1618        impl<'s, 'e> IntoMarker for [&'e Event; $len] where 'e: 's {
1619            fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1620                RawEventArray::from(self).into_marker(queue)
1621            }
1622        }
1623
1624        impl<'s, 'e> IntoMarker for [Option<&'e Event>; $len] where 'e: 's {
1625            fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1626                RawEventArray::from(self).into_marker(queue)
1627            }
1628        }
1629
1630        impl<'s, 'o, 'e> IntoMarker for [&'o Option<&'e Event>; $len] where 'e: 's + 'o, 'o: 's {
1631            fn into_marker(self, queue: &Queue) -> OclResult<Option<Event>> {
1632                RawEventArray::from(self).into_marker(queue)
1633            }
1634        }
1635    )*);
1636}
1637
1638impl_marker_arrays!(1, 2, 3, 4, 5, 6, 7, 8);
1639
1640/// Conversion to a stack allocated array of `cl_event` pointers.
1641pub trait IntoRawEventArray {
1642    fn into_raw_array(self) -> RawEventArray;
1643}
1644
1645impl<'s, 'e> IntoRawEventArray for &'s [&'e Event]
1646where
1647    'e: 's,
1648{
1649    fn into_raw_array(self) -> RawEventArray {
1650        RawEventArray::from(self)
1651    }
1652}
1653
1654impl<'s, 'e> IntoRawEventArray for &'s [Option<&'e Event>]
1655where
1656    'e: 's,
1657{
1658    fn into_raw_array(self) -> RawEventArray {
1659        RawEventArray::from(self)
1660    }
1661}
1662
1663impl<'s, 'o, 'e> IntoRawEventArray for &'s [&'o Option<&'e Event>]
1664where
1665    'e: 's + 'o,
1666    'o: 's,
1667{
1668    fn into_raw_array(self) -> RawEventArray {
1669        RawEventArray::from(self)
1670    }
1671}
1672
1673macro_rules! impl_raw_list_arrays {
1674    ($( $len:expr ),*) => ($(
1675        impl<'s, 'e> IntoRawEventArray  for [&'e Event; $len] where 'e: 's {
1676            fn into_raw_array(self) -> RawEventArray {
1677                RawEventArray::from(self)
1678            }
1679        }
1680
1681        impl<'s, 'e> IntoRawEventArray  for [Option<&'e Event>; $len] where 'e: 's {
1682            fn into_raw_array(self) -> RawEventArray {
1683                RawEventArray::from(self)
1684            }
1685        }
1686
1687        impl<'s, 'o, 'e> IntoRawEventArray  for [&'o Option<&'e Event>; $len] where 'e: 's + 'o, 'o: 's {
1688            fn into_raw_array(self) -> RawEventArray {
1689                RawEventArray::from(self)
1690            }
1691        }
1692    )*);
1693}
1694
1695impl_raw_list_arrays!(1, 2, 3, 4, 5, 6, 7, 8);