File: external_semaphore_linux.cpp

package info (click to toggle)
intel-compute-runtime 25.44.36015.8-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 79,632 kB
  • sloc: cpp: 931,547; lisp: 2,074; sh: 719; makefile: 162; python: 21
file content (131 lines) | stat: -rw-r--r-- 3,895 bytes parent folder | download
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
/*
 * Copyright (C) 2025 Intel Corporation
 *
 * SPDX-License-Identifier: MIT
 *
 */

#include "shared/source/os_interface/linux/external_semaphore_linux.h"

#include "shared/source/os_interface/external_semaphore.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/ioctl_helper.h"

namespace NEO {

std::unique_ptr<ExternalSemaphore> ExternalSemaphore::create(OSInterface *osInterface, ExternalSemaphore::Type type, void *handle, int fd, const char *name) {
    if (!osInterface) {
        return nullptr;
    }

    auto externalSemaphore = ExternalSemaphoreLinux::create(osInterface);

    bool result = externalSemaphore->importSemaphore(nullptr, fd, 0, nullptr, type, false);
    if (result == false) {
        return nullptr;
    }

    return externalSemaphore;
}

std::unique_ptr<ExternalSemaphoreLinux> ExternalSemaphoreLinux::create(OSInterface *osInterface) {
    auto externalSemaphoreLinux = std::make_unique<ExternalSemaphoreLinux>();
    externalSemaphoreLinux->osInterface = osInterface;
    externalSemaphoreLinux->state = SemaphoreState::Initial;

    return externalSemaphoreLinux;
}

bool ExternalSemaphoreLinux::importSemaphore(void *extHandle, int fd, uint32_t flags, const char *name, Type type, bool isNative) {
    switch (type) {
    case ExternalSemaphore::OpaqueFd:
    case ExternalSemaphore::TimelineSemaphoreFd:
        break;
    default:
        DEBUG_BREAK_IF(true);
        return false;
    }

    auto drm = this->osInterface->getDriverModel()->as<Drm>();

    struct SyncObjHandle args = {};
    args.fd = fd;
    args.handle = 0;

    auto ioctlHelper = drm->getIoctlHelper();

    int ret = ioctlHelper->ioctl(DrmIoctl::syncObjFdToHandle, &args);
    if (ret != 0) {
        return false;
    }

    this->syncHandle = args.handle;
    this->type = type;

    return true;
}

bool ExternalSemaphoreLinux::enqueueWait(uint64_t *fenceValue) {
    auto drm = this->osInterface->getDriverModel()->as<Drm>();
    auto ioctlHelper = drm->getIoctlHelper();

    if (this->type == ExternalSemaphore::TimelineSemaphoreFd) {
        struct SyncObjTimelineWait args = {};
        args.handles = reinterpret_cast<uintptr_t>(&this->syncHandle);
        args.points = reinterpret_cast<uintptr_t>(fenceValue);
        args.timeoutNs = 0;
        args.countHandles = 1u;
        args.flags = 0;

        int ret = ioctlHelper->ioctl(DrmIoctl::syncObjTimelineWait, &args);
        if (ret != 0) {
            return false;
        }
    } else {
        struct SyncObjWait args = {};
        args.handles = reinterpret_cast<uintptr_t>(&this->syncHandle);
        args.timeoutNs = 0;
        args.countHandles = 1u;
        args.flags = 0;

        int ret = ioctlHelper->ioctl(DrmIoctl::syncObjWait, &args);
        if (ret != 0) {
            return false;
        }
    }

    this->state = SemaphoreState::Signaled;

    return true;
}

bool ExternalSemaphoreLinux::enqueueSignal(uint64_t *fenceValue) {
    auto drm = this->osInterface->getDriverModel()->as<Drm>();
    auto ioctlHelper = drm->getIoctlHelper();

    if (this->type == ExternalSemaphore::TimelineSemaphoreFd) {
        struct SyncObjTimelineArray args = {};
        args.handles = reinterpret_cast<uintptr_t>(&this->syncHandle);
        args.points = reinterpret_cast<uintptr_t>(fenceValue);
        args.countHandles = 1u;

        int ret = ioctlHelper->ioctl(DrmIoctl::syncObjTimelineSignal, &args);
        if (ret != 0) {
            return false;
        }
    } else {
        struct SyncObjArray args = {};
        args.handles = reinterpret_cast<uintptr_t>(&this->syncHandle);
        args.countHandles = 1u;

        int ret = ioctlHelper->ioctl(DrmIoctl::syncObjSignal, &args);
        if (ret != 0) {
            return false;
        }
    }

    return true;
}

} // namespace NEO