2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #ifndef VULKAN_WSI_COMMON_QUEUE_H
25 #define VULKAN_WSI_COMMON_QUEUE_H
29 #include "util/u_vector.h"
32 struct u_vector vector
;
33 pthread_mutex_t mutex
;
38 wsi_queue_init(struct wsi_queue
*queue
, int length
)
42 uint32_t length_pow2
= 4;
43 while (length_pow2
< length
)
46 ret
= u_vector_init(&queue
->vector
, sizeof(uint32_t),
47 sizeof(uint32_t) * length_pow2
);
51 pthread_condattr_t condattr
;
52 ret
= pthread_condattr_init(&condattr
);
56 ret
= pthread_condattr_setclock(&condattr
, CLOCK_MONOTONIC
);
60 ret
= pthread_cond_init(&queue
->cond
, &condattr
);
64 ret
= pthread_mutex_init(&queue
->mutex
, NULL
);
68 pthread_condattr_destroy(&condattr
);
72 pthread_cond_destroy(&queue
->cond
);
74 pthread_condattr_destroy(&condattr
);
76 u_vector_finish(&queue
->vector
);
82 wsi_queue_destroy(struct wsi_queue
*queue
)
84 u_vector_finish(&queue
->vector
);
85 pthread_mutex_destroy(&queue
->mutex
);
86 pthread_cond_destroy(&queue
->cond
);
90 wsi_queue_push(struct wsi_queue
*queue
, uint32_t index
)
94 pthread_mutex_lock(&queue
->mutex
);
96 if (u_vector_length(&queue
->vector
) == 0)
97 pthread_cond_signal(&queue
->cond
);
99 elem
= u_vector_add(&queue
->vector
);
102 pthread_mutex_unlock(&queue
->mutex
);
105 #define NSEC_PER_SEC 1000000000
106 #define INT_TYPE_MAX(type) ((1ull << (sizeof(type) * 8 - 1)) - 1)
108 static inline VkResult
109 wsi_queue_pull(struct wsi_queue
*queue
, uint32_t *index
, uint64_t timeout
)
114 pthread_mutex_lock(&queue
->mutex
);
117 clock_gettime(CLOCK_MONOTONIC
, &now
);
119 uint32_t abs_nsec
= now
.tv_nsec
+ timeout
% NSEC_PER_SEC
;
120 uint64_t abs_sec
= now
.tv_sec
+ (abs_nsec
/ NSEC_PER_SEC
) +
121 (timeout
/ NSEC_PER_SEC
);
122 abs_nsec
%= NSEC_PER_SEC
;
124 /* Avoid roll-over in tv_sec on 32-bit systems if the user provided timeout
127 struct timespec abstime
;
128 abstime
.tv_nsec
= abs_nsec
;
129 abstime
.tv_sec
= MIN2(abs_sec
, INT_TYPE_MAX(abstime
.tv_sec
));
131 while (u_vector_length(&queue
->vector
) == 0) {
132 ret
= pthread_cond_timedwait(&queue
->cond
, &queue
->mutex
, &abstime
);
135 } else if (ret
== ETIMEDOUT
) {
139 /* Something went badly wrong */
140 result
= VK_ERROR_OUT_OF_DATE_KHR
;
145 uint32_t *elem
= u_vector_remove(&queue
->vector
);
150 pthread_mutex_unlock(&queue
->mutex
);
155 #endif /* VULKAN_WSI_COMMON_QUEUE_H */