1bf215546Sopenharmony_ci//
2bf215546Sopenharmony_ci// Copyright 2012 Francisco Jerez
3bf215546Sopenharmony_ci//
4bf215546Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci// copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci// to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci// and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci// Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci//
11bf215546Sopenharmony_ci// The above copyright notice and this permission notice shall be included in
12bf215546Sopenharmony_ci// all copies or substantial portions of the Software.
13bf215546Sopenharmony_ci//
14bf215546Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bf215546Sopenharmony_ci// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf215546Sopenharmony_ci// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17bf215546Sopenharmony_ci// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18bf215546Sopenharmony_ci// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19bf215546Sopenharmony_ci// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20bf215546Sopenharmony_ci// OTHER DEALINGS IN THE SOFTWARE.
21bf215546Sopenharmony_ci//
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ci#include "api/util.hpp"
24bf215546Sopenharmony_ci#include "core/queue.hpp"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ciusing namespace clover;
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ciCLOVER_API cl_command_queue
29bf215546Sopenharmony_ciclCreateCommandQueue(cl_context d_ctx, cl_device_id d_dev,
30bf215546Sopenharmony_ci                     cl_command_queue_properties props,
31bf215546Sopenharmony_ci                     cl_int *r_errcode) try {
32bf215546Sopenharmony_ci   auto &ctx = obj(d_ctx);
33bf215546Sopenharmony_ci   auto &dev = obj(d_dev);
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci   if (!count(dev, ctx.devices()))
36bf215546Sopenharmony_ci      throw error(CL_INVALID_DEVICE);
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   if (props & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
39bf215546Sopenharmony_ci                 CL_QUEUE_PROFILING_ENABLE))
40bf215546Sopenharmony_ci      throw error(CL_INVALID_VALUE);
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci   ret_error(r_errcode, CL_SUCCESS);
43bf215546Sopenharmony_ci   return new command_queue(ctx, dev, props);
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci} catch (error &e) {
46bf215546Sopenharmony_ci   ret_error(r_errcode, e);
47bf215546Sopenharmony_ci   return NULL;
48bf215546Sopenharmony_ci}
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ciCLOVER_API cl_int
51bf215546Sopenharmony_ciclRetainCommandQueue(cl_command_queue d_q) try {
52bf215546Sopenharmony_ci   obj(d_q).retain();
53bf215546Sopenharmony_ci   return CL_SUCCESS;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci} catch (error &e) {
56bf215546Sopenharmony_ci   return e.get();
57bf215546Sopenharmony_ci}
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ciCLOVER_API cl_int
60bf215546Sopenharmony_ciclReleaseCommandQueue(cl_command_queue d_q) try {
61bf215546Sopenharmony_ci   auto &q = obj(d_q);
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   q.flush();
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci   if (q.release())
66bf215546Sopenharmony_ci      delete pobj(d_q);
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   return CL_SUCCESS;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci} catch (error &e) {
71bf215546Sopenharmony_ci   return e.get();
72bf215546Sopenharmony_ci}
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ciCLOVER_API cl_int
75bf215546Sopenharmony_ciclGetCommandQueueInfo(cl_command_queue d_q, cl_command_queue_info param,
76bf215546Sopenharmony_ci                      size_t size, void *r_buf, size_t *r_size) try {
77bf215546Sopenharmony_ci   property_buffer buf { r_buf, size, r_size };
78bf215546Sopenharmony_ci   auto &q = obj(d_q);
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   switch (param) {
81bf215546Sopenharmony_ci   case CL_QUEUE_CONTEXT:
82bf215546Sopenharmony_ci      buf.as_scalar<cl_context>() = desc(q.context());
83bf215546Sopenharmony_ci      break;
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   case CL_QUEUE_DEVICE:
86bf215546Sopenharmony_ci      buf.as_scalar<cl_device_id>() = desc(q.device());
87bf215546Sopenharmony_ci      break;
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   case CL_QUEUE_REFERENCE_COUNT:
90bf215546Sopenharmony_ci      buf.as_scalar<cl_uint>() = q.ref_count();
91bf215546Sopenharmony_ci      break;
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   case CL_QUEUE_PROPERTIES:
94bf215546Sopenharmony_ci      buf.as_scalar<cl_command_queue_properties>() = q.props();
95bf215546Sopenharmony_ci      break;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   case CL_QUEUE_PROPERTIES_ARRAY:
98bf215546Sopenharmony_ci      buf.as_vector<cl_queue_properties>() = q.properties();
99bf215546Sopenharmony_ci      break;
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   case CL_QUEUE_DEVICE_DEFAULT:
102bf215546Sopenharmony_ci      if (r_size)
103bf215546Sopenharmony_ci	 *r_size = 0;
104bf215546Sopenharmony_ci      break;
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   case CL_QUEUE_SIZE:
107bf215546Sopenharmony_ci      throw error(CL_INVALID_COMMAND_QUEUE);
108bf215546Sopenharmony_ci      break;
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   default:
111bf215546Sopenharmony_ci      throw error(CL_INVALID_VALUE);
112bf215546Sopenharmony_ci   }
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci   return CL_SUCCESS;
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci} catch (error &e) {
117bf215546Sopenharmony_ci   return e.get();
118bf215546Sopenharmony_ci}
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ciCLOVER_API cl_int
121bf215546Sopenharmony_ciclFlush(cl_command_queue d_q) try {
122bf215546Sopenharmony_ci   obj(d_q).flush();
123bf215546Sopenharmony_ci   return CL_SUCCESS;
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci} catch (error &e) {
126bf215546Sopenharmony_ci   return e.get();
127bf215546Sopenharmony_ci}
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ciCLOVER_API cl_command_queue
130bf215546Sopenharmony_ciclCreateCommandQueueWithProperties(cl_context d_ctx, cl_device_id d_dev,
131bf215546Sopenharmony_ci                                   const cl_queue_properties *d_properties,
132bf215546Sopenharmony_ci                                   cl_int *r_errcode) try {
133bf215546Sopenharmony_ci   auto &ctx = obj(d_ctx);
134bf215546Sopenharmony_ci   auto &dev = obj(d_dev);
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ci   if (!count(dev, ctx.devices()))
137bf215546Sopenharmony_ci      throw error(CL_INVALID_DEVICE);
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   ret_error(r_errcode, CL_SUCCESS);
140bf215546Sopenharmony_ci   std::vector<cl_queue_properties> properties;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   if (d_properties) {
143bf215546Sopenharmony_ci      int idx = -1;
144bf215546Sopenharmony_ci      /* these come in pairs, bail if the first is 0 */
145bf215546Sopenharmony_ci      do {
146bf215546Sopenharmony_ci         idx++;
147bf215546Sopenharmony_ci         properties.push_back(d_properties[idx]);
148bf215546Sopenharmony_ci      } while (d_properties[idx & ~1]);
149bf215546Sopenharmony_ci   }
150bf215546Sopenharmony_ci   return new command_queue(ctx, dev, properties);
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci} catch (error &e) {
153bf215546Sopenharmony_ci   ret_error(r_errcode, e);
154bf215546Sopenharmony_ci   return NULL;
155bf215546Sopenharmony_ci}
156