Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/module/common/OCLThread.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

195 lines
4.2 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
//!
//! \file OCLThread.cpp
//!
#include <stdio.h>
#include <stdlib.h>
#include "OCL/Thread.h"
#ifdef _WIN32
#include <process.h>
#endif
//! pack the function pointer and data inside this struct
typedef struct __argsToThreadFunc {
oclThreadFunc func;
void* data;
} argsToThreadFunc;
#ifdef _WIN32
//! Windows thread callback - invokes the callback set by
//! the application in OCLThread constructor
unsigned _stdcall win32ThreadFunc(void* args) {
argsToThreadFunc* ptr = (argsToThreadFunc*)args;
OCLutil::Thread* obj = (OCLutil::Thread*)ptr->data;
ptr->func(obj->getData());
delete args;
return 0;
}
#endif
////////////////////////////////////////////////////////////////////
//!
//! Constructor for OCLLock
//!
OCLutil::Lock::Lock() {
#ifdef _WIN32
InitializeCriticalSection(&_cs);
#else
pthread_mutex_init(&_lock, NULL);
#endif
}
////////////////////////////////////////////////////////////////////
//!
//! Destructor for OCLLock
//!
OCLutil::Lock::~Lock() {
#ifdef _WIN32
DeleteCriticalSection(&_cs);
#else
pthread_mutex_destroy(&_lock);
#endif
}
//////////////////////////////////////////////////////////////
//!
//! Try to acquire the lock, wait for the lock if unavailable
//! else hold the lock and enter the protected area
//!
void OCLutil::Lock::lock() {
#ifdef _WIN32
EnterCriticalSection(&_cs);
#else
pthread_mutex_lock(&_lock);
#endif
}
//////////////////////////////////////////////////////////////
//!
//! Try to acquire the lock, if unavailable the function returns
//! false and returns true if available(enters the critical
//! section as well in this case).
//!
bool OCLutil::Lock::tryLock() {
#ifdef _WIN32
return (TryEnterCriticalSection(&_cs) != 0);
#else
return !((bool)pthread_mutex_trylock(&_lock));
#endif
}
//////////////////////////////////////////////////////////////
//!
//! Unlock the lock
//!
void OCLutil::Lock::unlock() {
#ifdef _WIN32
LeaveCriticalSection(&_cs);
#else
pthread_mutex_unlock(&_lock);
#endif
}
////////////////////////////////////////////////////////////////////
//!
//! Constructor for OCLThread
//!
OCLutil::Thread::Thread() : _tid(0), _data(0) {
#ifdef _WIN32
_ID = 0;
#else
#endif
}
////////////////////////////////////////////////////////////////////
//!
//! Destructor for OCLLock
//!
OCLutil::Thread::~Thread() {
#ifdef _WIN32
CloseHandle(_tid);
#else
#endif
}
//////////////////////////////////////////////////////////////
//!
//! Create a new thread and return the status of the operation
//!
bool OCLutil::Thread::create(oclThreadFunc func, void* arg) {
// Save the data internally
_data = arg;
unsigned int retVal;
bool verbose = getenv("VERBOSE") != NULL;
#ifdef _WIN32
// Setup the callback struct for thread function and pass to the
// begin thread routine
// xxx The following struct is allocated but never freed!!!!
argsToThreadFunc* args = new argsToThreadFunc;
args->func = func;
args->data = this;
_tid = (HANDLE)_beginthreadex(NULL, 0, win32ThreadFunc, args, 0, &retVal);
if (verbose) {
printf("Thread handle value = %p\n", _tid);
printf("Done creating thread. Thread id value = %u\n", retVal);
}
#else
//! Now create the thread with pointer to self as the data
retVal = pthread_create(&_tid, NULL, func, arg);
if (verbose)
printf("Done creating thread. Ret value %d, Self = %u\n", retVal, (unsigned int)pthread_self());
#endif
if (retVal != 0) return false;
return true;
}
//////////////////////////////////////////////////////////////
//!
//! Return the thread ID for the current OCLThread
//!
unsigned int OCLutil::Thread::getID() {
#ifdef _WIN32
return GetCurrentThreadId();
// Type cast the thread handle to unsigned in and send it over
#else
return (unsigned int)pthread_self();
#endif
}
//////////////////////////////////////////////////////////////
//!
//! Wait for this thread to join
//!
bool OCLutil::Thread::join() {
#ifdef _WIN32
DWORD rc = WaitForSingleObject(_tid, INFINITE);
if (rc == WAIT_FAILED) {
printf("Bad call to function(invalid handle?)\n");
}
#else
int rc = pthread_join(_tid, NULL);
#endif
if (rc != 0) return false;
return true;
}