我目前正在尝试Job系统的一些不同实现(基于this文章)。
我要解决的问题是将参数传递给“作业功能”。
这是我的Job
定义:
#define JOB_DATA_PADDING_SIZE 44
/** A job function is a function that can be worked on by the job manager */
typedef void( *JobFunction )( struct Job*, const void* );
/// <summary>
/// A job is something that represents work to be done by the thread pool.
/// Contains a pointer to it's work function and a counter to how many jobs
/// still need to be completed.
/// </summary>
struct Job
{
JobFunction Function; // 8 byte
Job* Parent; // 8 byte
std::atomic<int32_t> UnfinishedJobs; // 4 byte
char Padding[ JOB_DATA_PADDING_SIZE ]; // 44 bytes, so that this object fills
// a whole x64 cache line
};
如您所见,有char Padding
缓冲区必须存在,以避免虚假共享。我想使用该缓冲区作为一种简单地存储需要传递给用户正在调用的JobFunction
的参数的方法。此设置运行良好,但有一个例外:将指针作为参数传递。
当用户转到“创建工作”时,他们在JobManager
上调用此函数:
Job * JobManager::CreateJob( JobFunction aFunction, void* args, size_t aSize )
{
assert( aSize >= 0 && aSize < JOB_DATA_PADDING_SIZE );
Job* job = AllocateJob();
job->Function = aFunction;
job->Parent = nullptr;
job->UnfinishedJobs.store( 1 );
// Memcpy the args to the jobs padding
if ( args != nullptr )
{
memcpy( job->Padding, args, aSize );
}
return job;
}
如您所见,计划是将用户提供给函数的参数简单地memcpy
放入Padding
中。这适用于诸如struct之类的事情,实际上适用于小于44
个字节大小的任何数据。
我想做的是将memcpy
的给定指针插入到该Padding
数组中。但是,当我尝试这样做时,遇到了memcpy
复制指针处的值,然后将其复制到缓冲区的问题。
有没有办法我可以memcpy
实际的指针进入缓冲区?
我曾尝试过uint64_t
和uintptr_t
,但无济于事。
有没有办法做到这一点?我应该完全不对吗?
整个项目都位于GitHub上,如果这也有助于提供更多背景信息。
答案 0 :(得分:0)
有没有一种方法可以将实际的指针存储到缓冲区中?
当然。 Memcpy不在乎它要复制什么。它所做的只是将字节从源位置复制到目标位置。
假设您要复制一个int
值。 Memcpy不知道int
的值。它只知道位置。因此,您将不得不将该值放入某个内存位置(例如,放入int
变量)中,然后可以给memcpy一个指向它的指针。
extern void* destination_pointer;
int source = getIntValueFromWherever(); // put the value into the source location
size_t n_bytes = sizeof(source);
memcpy(destination_pointer, &source, n_bytes); // then give memcpy a pointer to it.
但是您想复制一个指针。好吧,这是同一笔交易。您要复制的内容(例如,某些foobar_t*
指针)必须存储在某个位置(例如,变量中)。然后,给memcpy指向源和目标位置的指针。
与上面的int
示例唯一不同的是source
变量的数据类型:
extern void* destination_pointer;
foobar_t* source = getPointerFromWherever(); // put the value into the source location
size_t n_bytes = sizeof(source);
memcpy(destination_pointer, &source, n_bytes); // then give memcpy a pointer to it.