Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Linux 32-bits encoded timestamp limitation - 2038K Bug #35

Open
wants to merge 1 commit into
base: omr1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions _studio/shared/umc/core/vm/src/vm_cond_linux32.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ int32_t vm_cond_is_valid(vm_cond *cond)
/* Init a condvar, return 1 if successful */
vm_status vm_cond_init(vm_cond *cond)
{
// pthread_condattr_t cond_attr;
pthread_condattr_t cond_attr;
int res = 0;

/* check error(s) */
Expand All @@ -69,16 +69,17 @@ vm_status vm_cond_init(vm_cond *cond)

vm_cond_destroy(cond);

// res = pthread_condattr_init(&cond_attr);
// if (!res)
res = pthread_condattr_init(&cond_attr);
if (!res)
{
res = pthread_cond_init(&cond->handle, NULL);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
res = pthread_cond_init(&cond->handle, &cond_attr);
cond->is_valid = !res;
if (res)
{
vm_cond_set_invalid_internal(cond);
}
// pthread_condattr_destroy(&mcond_attr);
pthread_condattr_destroy(&cond_attr);
}
return (res)? VM_OPERATION_FAILED: VM_OK;
} /* vm_status vm_cond_init(vm_cond *cond) */
Expand Down Expand Up @@ -114,16 +115,15 @@ vm_status vm_cond_timedwait(vm_cond *cond, vm_mutex *mutex, uint32_t msec)

if (cond->is_valid && mutex->is_valid)
{
struct timeval tval;
struct timespec tspec;
int32_t res;
unsigned long long micro_sec;
unsigned long long nano_sec;

gettimeofday(&tval, NULL);
// NOTE: micro_sec _should_ be unsigned long long, not uint32_t to avoid overflow
micro_sec = 1000 * msec + tval.tv_usec;
tspec.tv_sec = tval.tv_sec + (uint32_t)(micro_sec / 1000000);
tspec.tv_nsec = (uint32_t)(micro_sec % 1000000) * 1000;
clock_gettime(CLOCK_MONOTONIC, &tspec);
// NOTE: nano_sec _should_ be unsigned long long, not uint32_t to avoid overflow
nano_sec = 1000000 * msec + tspec.tv_nsec;
tspec.tv_sec += (uint32_t)(nano_sec / 1000000000);
tspec.tv_nsec = (uint32_t)(nano_sec % 1000000000);

res = pthread_cond_timedwait(&cond->handle, &mutex->handle, &tspec);
if (0 == res)
Expand All @@ -147,16 +147,15 @@ vm_status vm_cond_timed_uwait(vm_cond *cond, vm_mutex *mutex, vm_tick usec)

if (cond->is_valid && mutex->is_valid)
{
struct timeval tval;
struct timespec tspec;
int32_t res;
unsigned long long micro_sec;
unsigned long long nano_sec;

gettimeofday(&tval, NULL);
// NOTE: micro_sec _should_ be unsigned long long, not uint32_t to avoid overflow
micro_sec = usec + tval.tv_usec;
tspec.tv_sec = tval.tv_sec + (uint32_t)(micro_sec / 1000000);
tspec.tv_nsec = (uint32_t)(micro_sec % 1000000) * 1000;
clock_gettime(CLOCK_MONOTONIC, &tspec);
// NOTE: nano_sec _should_ be unsigned long long, not uint32_t to avoid overflow
nano_sec = 1000 * usec + tspec.tv_nsec;
tspec.tv_sec += (uint32_t)(nano_sec / 1000000000);
tspec.tv_nsec = (uint32_t)(nano_sec % 1000000000);

res = pthread_cond_timedwait(&cond->handle, &mutex->handle, &tspec);
if (0 == res)
Expand Down
33 changes: 20 additions & 13 deletions _studio/shared/umc/core/vm/src/vm_event_linux32.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ int32_t vm_event_is_valid(vm_event *event)
/* Init an event. Event is created unset. return 1 if success */
vm_status vm_event_init(vm_event *event, int32_t manual, int32_t state)
{
pthread_condattr_t cond_attr;
int res = 0;

/* check error(s) */
Expand All @@ -67,16 +68,23 @@ vm_status vm_event_init(vm_event *event, int32_t manual, int32_t state)

event->manual = manual;
event->state = state ? 1 : 0;
res = pthread_cond_init(&event->cond, 0);
res = pthread_condattr_init(&cond_attr);
if (!res)
{
res = pthread_mutex_init(&event->mutex, 0);
if (res)
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);

res = pthread_cond_init(&event->cond, &cond_attr);
if (!res)
{
int cres = pthread_cond_destroy(&event->cond);
assert(!cres); // we experienced undefined behavior
vm_event_set_invalid_internal(event);
res = pthread_mutex_init(&event->mutex, 0);
if (res)
{
int cres = pthread_cond_destroy(&event->cond);
assert(!cres); // we experienced undefined behavior
vm_event_set_invalid_internal(event);
}
}
pthread_condattr_destroy(&cond_attr);
}

return (res)? VM_OPERATION_FAILED: VM_OK;
Expand Down Expand Up @@ -292,16 +300,15 @@ vm_status vm_event_timed_wait(vm_event *event, uint32_t msec)
}
else
{
struct timeval tval;
struct timespec tspec;
int32_t i_res;
unsigned long long micro_sec;
unsigned long long nano_sec;

gettimeofday(&tval, NULL);
// NOTE: micro_sec _should_ be unsigned long long, not uint32_t to avoid overflow
micro_sec = 1000 * msec + tval.tv_usec;
tspec.tv_sec = tval.tv_sec + (uint32_t)(micro_sec / 1000000);
tspec.tv_nsec = (uint32_t)(micro_sec % 1000000) * 1000;
clock_gettime(CLOCK_MONOTONIC, &tspec);
// NOTE: nano_sec _should_ be unsigned long long, not uint32_t to avoid overflow
nano_sec = 1000000 * msec + tspec.tv_nsec;
tspec.tv_sec += (uint32_t)(nano_sec / 1000000000);
tspec.tv_nsec = (uint32_t)(nano_sec % 1000000000);
i_res = 0;

while (!i_res && !event->state)
Expand Down
48 changes: 31 additions & 17 deletions _studio/shared/umc/core/vm/src/vm_semaphore_linux32.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ int32_t vm_semaphore_is_valid(vm_semaphore *sem)
/* Init a semaphore with value */
vm_status vm_semaphore_init(vm_semaphore *sem, int32_t init_count)
{
pthread_condattr_t cond_attr;
int res = 0;

/* check error(s) */
Expand All @@ -69,16 +70,22 @@ vm_status vm_semaphore_init(vm_semaphore *sem, int32_t init_count)

sem->count = init_count;
sem->max_count = 1;
res = pthread_cond_init(&sem->cond, 0);
res = pthread_condattr_init(&cond_attr);
if (!res)
{
res = pthread_mutex_init(&sem->mutex, 0);
if (res)
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
res = pthread_cond_init(&sem->cond, &cond_attr);
if (!res)
{
int cres = pthread_cond_destroy(&sem->cond);
assert(!cres); // we experienced undefined behavior
vm_semaphore_set_invalid_internal(sem);
res = pthread_mutex_init(&sem->mutex, 0);
if (res)
{
int cres = pthread_cond_destroy(&sem->cond);
assert(!cres); // we experienced undefined behavior
vm_semaphore_set_invalid_internal(sem);
}
}
pthread_condattr_destroy(&cond_attr);
}

return (res)? VM_OPERATION_FAILED: VM_OK;
Expand All @@ -88,23 +95,30 @@ vm_status vm_semaphore_init(vm_semaphore *sem, int32_t init_count)
vm_status vm_semaphore_init_max(vm_semaphore *sem, int32_t init_count, int32_t max_count)
{
int res = 0;
pthread_condattr_t cond_attr;

/* check error(s) */
if (NULL == sem)
return VM_NULL_PTR;

sem->count = init_count;
sem->max_count = max_count;
res = pthread_cond_init(&sem->cond, 0);
res = pthread_condattr_init(&cond_attr);
if (!res)
{
res = pthread_mutex_init(&sem->mutex, 0);
if (res)
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
res = pthread_cond_init(&sem->cond, &cond_attr);
if (!res)
{
int cres = pthread_cond_destroy(&sem->cond);
assert(!res); // we experienced undefined behavior
vm_semaphore_set_invalid_internal(sem);
res = pthread_mutex_init(&sem->mutex, 0);
if (res)
{
int cres = pthread_cond_destroy(&sem->cond);
assert(!res); // we experienced undefined behavior
vm_semaphore_set_invalid_internal(sem);
}
}
pthread_condattr_destroy(&cond_attr);
}

return (res)? VM_OPERATION_FAILED: VM_OK;
Expand All @@ -130,13 +144,13 @@ vm_status vm_semaphore_timedwait(vm_semaphore *sem, uint32_t msec)
{
if (0 == sem->count)
{
struct timeval tval;
struct timespec tspec;
unsigned long long nano_sec;

gettimeofday(&tval, NULL);
msec = 1000 * msec + tval.tv_usec;
tspec.tv_sec = tval.tv_sec + msec / 1000000;
tspec.tv_nsec = (msec % 1000000) * 1000;
clock_gettime(CLOCK_MONOTONIC, &tspec);
nano_sec = 1000000 * msec + tspec.tv_nsec;
tspec.tv_sec += (uint32_t)(nano_sec / 1000000000);
tspec.tv_nsec = (uint32_t)(nano_sec % 1000000000);
i_res = 0;
while (!i_res && !sem->count)
{
Expand Down