Fence.cpp revision 221de2a33d456738f7f64db0b015a960211d4834
1f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis/*
2f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Copyright (C) 2012 The Android Open Source Project
3f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis *
4f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
5f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * you may not use this file except in compliance with the License.
6f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * You may obtain a copy of the License at
7f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis *
8f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
9f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis *
10f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Unless required by applicable law or agreed to in writing, software
11f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
12f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * See the License for the specific language governing permissions and
14f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * limitations under the License.
15f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis */
16f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
17f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define LOG_TAG "Fence"
18f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis//#define LOG_NDEBUG 0
20f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
21d31824004277f554000417cea349d69f18655e95Dan Stoza// We would eliminate the non-conforming zero-length array, but we can't since
22d31824004277f554000417cea349d69f18655e95Dan Stoza// this is effectively included from the Linux kernel
23d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic push
24d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic ignored "-Wzero-length-array"
25f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <sync/sync.h>
26d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic pop
27d31824004277f554000417cea349d69f18655e95Dan Stoza
28f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <ui/Fence.h>
29f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <unistd.h>
30f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Log.h>
31f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Trace.h>
32f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
33f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisnamespace android {
34f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
351df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennisconst sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);
36ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall
37f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence() :
38f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    mFenceFd(-1) {
39f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
40f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
41f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence(int fenceFd) :
42f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    mFenceFd(fenceFd) {
43f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
44f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
45f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::~Fence() {
46f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (mFenceFd != -1) {
47f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        close(mFenceFd);
48f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
49f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
50f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
51d31824004277f554000417cea349d69f18655e95Dan Stozastatus_t Fence::wait(int timeout) {
52f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    ATRACE_CALL();
53f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (mFenceFd == -1) {
54f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        return NO_ERROR;
55f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
56b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    int err = sync_wait(mFenceFd, timeout);
57b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    return err < 0 ? -errno : status_t(NO_ERROR);
58f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
59f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
60ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopianstatus_t Fence::waitForever(const char* logname) {
61ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    ATRACE_CALL();
62ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    if (mFenceFd == -1) {
63ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall        return NO_ERROR;
64ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    }
65d31824004277f554000417cea349d69f18655e95Dan Stoza    int warningTimeout = 3000;
66ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    int err = sync_wait(mFenceFd, warningTimeout);
67b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    if (err < 0 && errno == ETIME) {
68ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall        ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
69ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall                warningTimeout);
70ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall        err = sync_wait(mFenceFd, TIMEOUT_NEVER);
71ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    }
72b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    return err < 0 ? -errno : status_t(NO_ERROR);
73ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall}
74ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall
75fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyacksp<Fence> Fence::merge(const char* name, const sp<Fence>& f1,
76f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        const sp<Fence>& f2) {
77f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    ATRACE_CALL();
781df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    int result;
791df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    // Merge the two fences.  In the case where one of the fences is not a
801df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
811df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    // that a new fence with the given name is created.
821df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    if (f1->isValid() && f2->isValid()) {
83fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack        result = sync_merge(name, f1->mFenceFd, f2->mFenceFd);
841df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    } else if (f1->isValid()) {
85fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack        result = sync_merge(name, f1->mFenceFd, f1->mFenceFd);
861df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    } else if (f2->isValid()) {
87fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack        result = sync_merge(name, f2->mFenceFd, f2->mFenceFd);
881df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    } else {
891df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis        return NO_FENCE;
901df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    }
91f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (result == -1) {
92d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian        status_t err = -errno;
93d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian        ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
94fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack                name, f1->mFenceFd, f2->mFenceFd,
95d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian                strerror(-err), err);
96ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        return NO_FENCE;
97f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
98f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return sp<Fence>(new Fence(result));
99f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
100f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
101fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyacksp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
102fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack        const sp<Fence>& f2) {
103fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack    return merge(name.string(), f1, f2);
104fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack}
105fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack
106f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hallint Fence::dup() const {
107f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall    return ::dup(mFenceFd);
108f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall}
109f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall
11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnsecs_t Fence::getSignalTime() const {
11182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    if (mFenceFd == -1) {
112221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return SIGNAL_TIME_INVALID;
11382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
11482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
11582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
11682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    if (finfo == NULL) {
11782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd);
118221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return SIGNAL_TIME_INVALID;
11982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
12082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    if (finfo->status != 1) {
1217c36cd231542990e0ef8240fcc8dfd35a9e4b38bJesse Hall        sync_fence_info_free(finfo);
122221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return SIGNAL_TIME_PENDING;
12382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
12482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
12582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    struct sync_pt_info* pinfo = NULL;
12682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    uint64_t timestamp = 0;
12782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
12882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        if (pinfo->timestamp_ns > timestamp) {
12982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis            timestamp = pinfo->timestamp_ns;
13082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis        }
13182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    }
13282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    sync_fence_info_free(finfo);
13382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
13482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis    return nsecs_t(timestamp);
13582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis}
13682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis
137f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFlattenedSize() const {
1386fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza    return 4;
139f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
140f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
141f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFdCount() const {
1421df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    return isValid() ? 1 : 0;
143f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
144f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
145e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
146e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    if (size < getFlattenedSize() || count < getFdCount()) {
147e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        return NO_MEMORY;
148f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
1496fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza    // Cast to uint32_t since the size of a size_t can vary between 32- and
1506fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza    // 64-bit processes
1516fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount()));
1521df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    if (isValid()) {
153e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        *fds++ = mFenceFd;
154e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        count--;
1551df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    }
156f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return NO_ERROR;
157f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
158f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
159e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) {
160f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (mFenceFd != -1) {
161f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        // Don't unflatten if we already have a valid fd.
162f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        return INVALID_OPERATION;
163f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
164f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
165e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    if (size < 1) {
166e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        return NO_MEMORY;
167e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    }
168e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian
169288f2ef6294b99a4a53355273ae8ad0f5a525f65Colin Cross    uint32_t numFds;
170e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    FlattenableUtils::read(buffer, size, numFds);
171e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian
172e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    if (numFds > 1) {
173e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        return BAD_VALUE;
174e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    }
175e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian
176e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    if (count < numFds) {
177e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        return NO_MEMORY;
178e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    }
179e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian
180e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian    if (numFds) {
181e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        mFenceFd = *fds++;
182e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian        count--;
1831df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis    }
1841df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis
185f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return NO_ERROR;
186f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
187f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
188f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} // namespace android
189