summaryrefslogtreecommitdiff
path: root/src/core/commandqueue.h
blob: 0ea10bd900543fd016f5e5c7ccb5cd320fe9f37c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#ifndef __COMMANDQUEUE_H__
#define __COMMANDQUEUE_H__

#include "object.h"

#include <CL/cl.h>
#include <pthread.h>

#include <map>
#include <list>

namespace Coal
{

class Context;
class DeviceInterface;
class Event;

class CommandQueue : public Object
{
    public:
        CommandQueue(Context *ctx,
                     DeviceInterface *device,
                     cl_command_queue_properties properties,
                     cl_int *errcode_ret);
        ~CommandQueue();

        cl_int queueEvent(Event *event);

        cl_int info(cl_command_queue_info param_name,
                    size_t param_value_size,
                    void *param_value,
                    size_t *param_value_size_ret) const;

        cl_int setProperty(cl_command_queue_properties properties,
                           cl_bool enable,
                           cl_command_queue_properties *old_properties);

        cl_int checkProperties() const;
        void pushEventsOnDevice();
        void cleanEvents();

        Event **events(unsigned int &count); /*!< @note Retains all the events */

    private:
        DeviceInterface *p_device;
        cl_command_queue_properties p_properties;

        std::list<Event *> p_events;
        pthread_mutex_t p_event_list_mutex;
};

class Event : public Object
{
    public:
        enum Type
        {
            NDRangeKernel = CL_COMMAND_NDRANGE_KERNEL,
            TaskKernel = CL_COMMAND_TASK,
            NativeKernel = CL_COMMAND_NATIVE_KERNEL,
            ReadBuffer = CL_COMMAND_READ_BUFFER,
            WriteBuffer = CL_COMMAND_WRITE_BUFFER,
            CopyBuffer = CL_COMMAND_COPY_BUFFER,
            ReadImage = CL_COMMAND_READ_IMAGE,
            WriteImage = CL_COMMAND_WRITE_IMAGE,
            CopyImage = CL_COMMAND_COPY_IMAGE,
            CopyImageToBuffer = CL_COMMAND_COPY_IMAGE_TO_BUFFER,
            CopyBufferToImage = CL_COMMAND_COPY_BUFFER_TO_IMAGE,
            MapBuffer = CL_COMMAND_MAP_BUFFER,
            MapImage = CL_COMMAND_MAP_IMAGE,
            UnmapMemObject = CL_COMMAND_UNMAP_MEM_OBJECT,
            Marker = CL_COMMAND_MARKER,
            AcquireGLObjects = CL_COMMAND_ACQUIRE_GL_OBJECTS,
            ReleaseGLObjects = CL_COMMAND_RELEASE_GL_OBJECTS,
            ReadBufferRect = CL_COMMAND_READ_BUFFER_RECT,
            WriteBufferRect = CL_COMMAND_WRITE_BUFFER_RECT,
            CopyBufferRect = CL_COMMAND_COPY_BUFFER_RECT,
            User = CL_COMMAND_USER,
            Barrier,
            WaitForEvents
        };

        enum Status
        {
            Queued = CL_QUEUED,
            Submitted = CL_SUBMITTED,
            Running = CL_RUNNING,
            Complete = CL_COMPLETE
        };

        typedef void (CL_CALLBACK *event_callback)(cl_event, cl_int, void *);

        struct CallbackData
        {
            event_callback callback;
            void *user_data;
        };

        enum Timing
        {
            Queue,
            Submit,
            Start,
            End,
            Max
        };

    public:
        Event(CommandQueue *parent,
              Status status,
              cl_uint num_events_in_wait_list,
              const Event **event_wait_list,
              cl_int *errcode_ret);

        virtual ~Event();

        virtual Type type() const = 0;
        bool isDummy() const;      /*!< Doesn't do anything, it's just an event type */

        void setStatus(Status status);
        void setDeviceData(void *data);
        void updateTiming(Timing timing);
        Status status() const;
        void waitForStatus(Status status);
        void *deviceData();

        const Event **waitEvents(cl_uint &count) const;

        void setCallback(cl_int command_exec_callback_type,
                         event_callback callback,
                         void *user_data);

        cl_int info(cl_event_info param_name,
                    size_t param_value_size,
                    void *param_value,
                    size_t *param_value_size_ret) const;
        cl_int profilingInfo(cl_profiling_info param_name,
                             size_t param_value_size,
                             void *param_value,
                             size_t *param_value_size_ret) const;
    private:
        cl_uint p_num_events_in_wait_list;
        const Event **p_event_wait_list;

        pthread_cond_t p_state_change_cond;
        pthread_mutex_t p_state_mutex;

        Status p_status;
        void *p_device_data;
        std::multimap<Status, CallbackData> p_callbacks;

        cl_uint p_timing[Max];
};

}

struct _cl_command_queue : public Coal::CommandQueue
{};

struct _cl_event : public Coal::Event
{};

#endif