kronos_compute/api/
sync.rs

1//! Safe synchronization primitives
2
3use super::*;
4use crate::*; // Import all functions from the crate root
5use std::ptr;
6
7/// A GPU fence for CPU-GPU synchronization
8pub struct Fence {
9    context: ComputeContext,
10    fence: VkFence,
11}
12
13// Send + Sync for thread safety
14unsafe impl Send for Fence {}
15unsafe impl Sync for Fence {}
16
17/// A GPU semaphore for GPU-GPU synchronization
18pub struct Semaphore {
19    context: ComputeContext,
20    semaphore: VkSemaphore,
21}
22
23// Send + Sync for thread safety
24unsafe impl Send for Semaphore {}
25unsafe impl Sync for Semaphore {}
26
27impl ComputeContext {
28    /// Create a new fence
29    pub fn create_fence(&self, signaled: bool) -> Result<Fence> {
30        unsafe {
31            self.with_inner(|inner| {
32                let create_info = VkFenceCreateInfo {
33                    sType: VkStructureType::FenceCreateInfo,
34                    pNext: ptr::null(),
35                    flags: if signaled { VkFenceCreateFlags::SIGNALED } else { VkFenceCreateFlags::empty() },
36                };
37                
38                let mut fence = VkFence::NULL;
39                let result = vkCreateFence(inner.device, &create_info, ptr::null(), &mut fence);
40                
41                if result != VkResult::Success {
42                    return Err(KronosError::SynchronizationError(
43                        format!("vkCreateFence failed: {:?}", result)
44                    ));
45                }
46                
47                Ok(Fence {
48                    context: self.clone(),
49                    fence,
50                })
51            })
52        }
53    }
54    
55    /// Create a new semaphore
56    pub fn create_semaphore(&self) -> Result<Semaphore> {
57        unsafe {
58            self.with_inner(|inner| {
59                let create_info = VkSemaphoreCreateInfo {
60                    sType: VkStructureType::SemaphoreCreateInfo,
61                    pNext: ptr::null(),
62                    flags: 0,
63                };
64                
65                let mut semaphore = VkSemaphore::NULL;
66                let result = vkCreateSemaphore(inner.device, &create_info, ptr::null(), &mut semaphore);
67                
68                if result != VkResult::Success {
69                    return Err(KronosError::SynchronizationError(
70                        format!("vkCreateSemaphore failed: {:?}", result)
71                    ));
72                }
73                
74                Ok(Semaphore {
75                    context: self.clone(),
76                    semaphore,
77                })
78            })
79        }
80    }
81}
82
83impl Fence {
84    /// Wait for the fence to be signaled
85    pub fn wait(&self, timeout_ns: u64) -> Result<()> {
86        unsafe {
87            self.context.with_inner(|inner| {
88                let result = vkWaitForFences(
89                    inner.device,
90                    1,
91                    &self.fence,
92                    VK_TRUE,
93                    timeout_ns,
94                );
95                
96                match result {
97                    VkResult::Success => Ok(()),
98                    VkResult::Timeout => Err(KronosError::SynchronizationError("Timeout waiting for fence".into())),
99                    _ => Err(KronosError::from(result)),
100                }
101            })
102        }
103    }
104    
105    /// Wait indefinitely for the fence
106    pub fn wait_forever(&self) -> Result<()> {
107        self.wait(u64::MAX)
108    }
109    
110    /// Reset the fence to unsignaled state
111    pub fn reset(&self) -> Result<()> {
112        unsafe {
113            self.context.with_inner(|inner| {
114                let result = vkResetFences(inner.device, 1, &self.fence);
115                
116                if result != VkResult::Success {
117                    return Err(KronosError::from(result));
118                }
119                
120                Ok(())
121            })
122        }
123    }
124    
125    /// Check if the fence is signaled without waiting
126    pub fn is_signaled(&self) -> Result<bool> {
127        unsafe {
128            self.context.with_inner(|inner| {
129                let result = vkGetFenceStatus(inner.device, self.fence);
130                
131                match result {
132                    VkResult::Success => Ok(true),
133                    VkResult::NotReady => Ok(false),
134                    _ => Err(KronosError::from(result)),
135                }
136            })
137        }
138    }
139    
140    /// Get the raw Vulkan fence handle
141    pub fn raw(&self) -> VkFence {
142        self.fence
143    }
144}
145
146impl Semaphore {
147    /// Get the raw Vulkan semaphore handle
148    pub fn raw(&self) -> VkSemaphore {
149        self.semaphore
150    }
151}
152
153impl Drop for Fence {
154    fn drop(&mut self) {
155        unsafe {
156            self.context.with_inner(|inner| {
157                vkDestroyFence(inner.device, self.fence, ptr::null());
158            });
159        }
160    }
161}
162
163impl Drop for Semaphore {
164    fn drop(&mut self) {
165        unsafe {
166            self.context.with_inner(|inner| {
167                vkDestroySemaphore(inner.device, self.semaphore, ptr::null());
168            });
169        }
170    }
171}