From 6be73f561a8fc19b2303a4dd60117fa976c3d30d Mon Sep 17 00:00:00 2001 From: ajesh Date: Mon, 25 Feb 2019 11:12:01 +0530 Subject: [PATCH] gpu: nvgpu: use posix cond implementation for qnx Unify posix cond unit with qnx. Jira NVGPU-2151 Change-Id: I769f646751299154d7d753228777266e3098c8d3 Signed-off-by: ajesh Reviewed-on: https://git-master.nvidia.com/r/2033596 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile.sources | 2 +- drivers/gpu/nvgpu/include/nvgpu/cond.h | 6 +- drivers/gpu/nvgpu/include/nvgpu/posix/cond.h | 66 ++++++---------- drivers/gpu/nvgpu/os/posix/cond.c | 80 ++++++++++++++++---- 4 files changed, 93 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index 9803b78ff..415079738 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -36,7 +36,6 @@ srcs += os/posix/nvgpu.c \ os/posix/firmware.c \ os/posix/soc.c \ os/posix/rwsem.c \ - os/posix/cond.c \ os/posix/thread.c \ os/posix/error_notifier.c \ os/posix/fuse.c \ @@ -56,6 +55,7 @@ endif # POSIX sources shared between the POSIX and QNX builds. srcs += os/posix/bug.c \ os/posix/bsearch.c \ + os/posix/cond.c \ os/posix/lock.c srcs += common/sim.c \ diff --git a/drivers/gpu/nvgpu/include/nvgpu/cond.h b/drivers/gpu/nvgpu/include/nvgpu/cond.h index 2fadd2f75..48002490b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/cond.h +++ b/drivers/gpu/nvgpu/include/nvgpu/cond.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,10 +25,8 @@ #ifdef __KERNEL__ #include -#elif defined(__NVGPU_POSIX__) -#include #else -#include +#include #endif /* diff --git a/drivers/gpu/nvgpu/include/nvgpu/posix/cond.h b/drivers/gpu/nvgpu/include/nvgpu/posix/cond.h index 4610bc613..170a4851e 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/posix/cond.h +++ b/drivers/gpu/nvgpu/include/nvgpu/posix/cond.h @@ -25,7 +25,6 @@ #include #include -#include struct nvgpu_cond { bool initialized; @@ -34,59 +33,30 @@ struct nvgpu_cond { pthread_condattr_t attr; }; +int nvgpu_cond_timedwait(struct nvgpu_cond *c, unsigned int *ms); /** * NVGPU_COND_WAIT - Wait for a condition to be true * - * @c - The condition variable to sleep on + * @cond - The condition variable to sleep on * @condition - The condition that needs to be true * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait. - * This parameter must be a u32. Since this is a macro, this is - * enforced by assigning a typecast NULL pointer to a u32 tmp - * variable which will generate a compiler warning (or error if - * the warning is configured as an error). + * This parameter must be a u32. * * Wait for a condition to become true. Returns -ETIMEOUT if * the wait timed out with condition false. */ -#define NVGPU_COND_WAIT(c, condition, timeout_ms) \ -({ \ - int ret = 0; \ - struct timespec ts; \ - long tmp_timeout_ms; \ - /* This is the assignment to enforce a u32 for timeout_ms */ \ - u32 *tmp = (typeof(timeout_ms) *)NULL; \ - (void)tmp; \ - if ((sizeof(long) <= sizeof(u32)) && \ - ((timeout_ms) >= (u32)LONG_MAX)) { \ - tmp_timeout_ms = LONG_MAX; \ - } else { \ - tmp_timeout_ms = (long)(timeout_ms); \ - } \ - nvgpu_mutex_acquire(&(c)->mutex); \ - if (tmp_timeout_ms == 0) { \ - ret = pthread_cond_wait(&(c)->cond, \ - &(c)->mutex.lock.mutex); \ - } else { \ - clock_gettime(CLOCK_REALTIME, &ts); \ - ts.tv_sec += tmp_timeout_ms / 1000; \ - ts.tv_nsec += (tmp_timeout_ms % 1000) * 1000000; \ - if (ts.tv_nsec >= 1000000000) { \ - ts.tv_sec += 1; \ - ts.tv_nsec %= 1000000000; \ - } \ - while (!(condition) && ret == 0) { \ - ret = pthread_cond_timedwait(&(c)->cond, \ - &(c)->mutex.lock.mutex, &ts); \ - } \ - } \ - nvgpu_mutex_release(&(c)->mutex); \ - ret; \ +#define NVGPU_COND_WAIT(cond, condition, timeout_ms) \ +({ \ + int ret = 0; \ + NVGPU_COND_WAIT_TIMEOUT(cond, condition, ret, \ + timeout_ms ? timeout_ms : (unsigned int)-1); \ + ret; \ }) /** * NVGPU_COND_WAIT_INTERRUPTIBLE - Wait for a condition to be true * - * @c - The condition variable to sleep on + * @cond - The condition variable to sleep on * @condition - The condition that needs to be true * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait * @@ -94,7 +64,19 @@ struct nvgpu_cond { * the wait timed out with condition false or -ERESTARTSYS on * signal. */ -#define NVGPU_COND_WAIT_INTERRUPTIBLE(c, condition, timeout_ms) \ - NVGPU_COND_WAIT(c, condition, timeout_ms) +#define NVGPU_COND_WAIT_INTERRUPTIBLE(cond, condition, timeout_ms) \ + NVGPU_COND_WAIT(cond, condition, timeout_ms) + + +#define NVGPU_COND_WAIT_TIMEOUT(cond, condition, ret, timeout_ms) \ +do { \ + unsigned int __timeout = timeout_ms; \ + ret = 0; \ + nvgpu_mutex_acquire(&(cond)->mutex); \ + while (!(condition) && ret == 0) { \ + ret = nvgpu_cond_timedwait(cond, &__timeout); \ + } \ + nvgpu_mutex_release(&(cond)->mutex); \ +} while (0) #endif /* NVGPU_POSIX_COND_H */ diff --git a/drivers/gpu/nvgpu/os/posix/cond.c b/drivers/gpu/nvgpu/os/posix/cond.c index 02e7826e1..d9cb50ad5 100644 --- a/drivers/gpu/nvgpu/os/posix/cond.c +++ b/drivers/gpu/nvgpu/os/posix/cond.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,27 +22,40 @@ #include -#include - int nvgpu_cond_init(struct nvgpu_cond *cond) { int ret; + + ret = pthread_condattr_init(&cond->attr); + if (ret != 0) { + return ret; + } + ret = pthread_condattr_setclock(&cond->attr, CLOCK_MONOTONIC); + if (ret != 0) { + (void) pthread_condattr_destroy(&cond->attr); + return ret; + } + ret = nvgpu_mutex_init(&cond->mutex); if (ret != 0) { + (void) pthread_condattr_destroy(&cond->attr); return ret; } - ret = pthread_cond_init(&cond->cond, NULL); + + ret = pthread_cond_init(&cond->cond, &cond->attr); if (ret != 0) { - nvgpu_mutex_destroy(&cond->mutex); + (void) pthread_condattr_destroy(&cond->attr); + (void) nvgpu_mutex_destroy(&cond->mutex); return ret; } + cond->initialized = true; return ret; } void nvgpu_cond_signal(struct nvgpu_cond *cond) { - if (cond == NULL || !cond->initialized) { + if ((cond == NULL) || !(cond->initialized)) { BUG(); } nvgpu_mutex_acquire(&cond->mutex); @@ -52,7 +65,7 @@ void nvgpu_cond_signal(struct nvgpu_cond *cond) void nvgpu_cond_signal_interruptible(struct nvgpu_cond *cond) { - if (cond == NULL || !cond->initialized) { + if ((cond == NULL) || !(cond->initialized)) { BUG(); } nvgpu_mutex_acquire(&cond->mutex); @@ -63,8 +76,9 @@ void nvgpu_cond_signal_interruptible(struct nvgpu_cond *cond) int nvgpu_cond_broadcast(struct nvgpu_cond *cond) { int ret; - if (cond == NULL || !cond->initialized) { - BUG(); + + if ((cond == NULL) || !(cond->initialized)) { + return -EINVAL; } nvgpu_mutex_acquire(&cond->mutex); ret = pthread_cond_broadcast(&cond->cond); @@ -75,8 +89,9 @@ int nvgpu_cond_broadcast(struct nvgpu_cond *cond) int nvgpu_cond_broadcast_interruptible(struct nvgpu_cond *cond) { int ret; - if (cond == NULL || !cond->initialized) { - BUG(); + + if ((cond == NULL) || !(cond->initialized)) { + return -EINVAL; } nvgpu_mutex_acquire(&cond->mutex); ret = pthread_cond_broadcast(&cond->cond); @@ -86,11 +101,48 @@ int nvgpu_cond_broadcast_interruptible(struct nvgpu_cond *cond) void nvgpu_cond_destroy(struct nvgpu_cond *cond) { - if (cond == NULL || !cond->initialized) { + if (cond == NULL) { BUG(); } + (void) pthread_cond_destroy(&cond->cond); nvgpu_mutex_destroy(&cond->mutex); - pthread_cond_destroy(&cond->cond); + (void) pthread_condattr_destroy(&cond->attr); cond->initialized = false; - return; +} + +int nvgpu_cond_timedwait(struct nvgpu_cond *c, unsigned int *ms) +{ + int ret; + s64 t_start_ns, t_ns; + struct timespec ts; + + if (*ms == (unsigned int)-1) { + return pthread_cond_wait(&c->cond, &c->mutex.lock.mutex); + } + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { + return -EFAULT; + } + + t_start_ns = ts.tv_sec * 1000000000 + ts.tv_nsec; + t_ns = (s64)(*ms); + t_ns *= 1000000; + t_ns += t_start_ns; + ts.tv_sec = t_ns / 1000000000; + ts.tv_nsec = t_ns % 1000000000; + + ret = pthread_cond_timedwait(&c->cond, &c->mutex.lock.mutex, &ts); + if (ret == 0) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) { + t_ns = ((ts.tv_sec * 1000000000) + + ts.tv_nsec) - t_start_ns; + t_ns /= 1000000; + if (*ms <= (unsigned int)t_ns) { + *ms = 0; + } else { + *ms -= (unsigned int)t_ns; + } + } + } + return ret; }