I want to create a thread with a separate file descriptor table to have better performance with kevent. In Linux, I was using unshare syscall to achieve this, which as far as I know there is no equivalent or similar syscall in FreeBSD. Then I tried creating such thread directly with rfork via its wrapper rfork_thread. But it does not work correctly, usually it terminates in the middle of the function and waitpid collected status with 0x8b (or some other code that does not match with any number in bits/waitstatus.h).
While I am trying to debug the kernel to find out what are the problems, I would like to post my test code here to see if anyone sees a problem, which can greatly save my time. The test code runs well except status in the end is not zero. I implemented same logic in my program and the status is 0x8b which I guess is because of invalid page access.
Thanks for any help in advance!
While I am trying to debug the kernel to find out what are the problems, I would like to post my test code here to see if anyone sees a problem, which can greatly save my time. The test code runs well except status in the end is not zero. I implemented same logic in my program and the status is 0x8b which I guess is because of invalid page access.
Thanks for any help in advance!
C++:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <vector>
const size_t VEC_SIZE = 1000;
static int thread_routine(void* arg) {
std::cout<<"init thread "<<arg<<std::endl;
// the problem seems related to some memory allocation
std::vector<int>** vectors = new std::vector<int>*[VEC_SIZE];
for(int i = 0; i < VEC_SIZE; i++) {
vectors[i] = new std::vector<int>(10000);
std::cout<<"vec "<<i<<" initialized"<<std::endl;
}
}
int main() {
const int STACK_SIZE = 8000000;
//void* stackaddr = malloc(STACK_SIZE); // should also work
void* stackaddr = mmap(NULL, STACK_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0);
std::cout<<"stackaddr: 0x"<<std::hex<<stackaddr<<std::endl;
void* stacktop = (char*)stackaddr + STACK_SIZE; // assuming stack going downwards
pid_t child = 0;
child = rfork_thread(RFFDG|RFPROC|RFMEM|RFSIGSHARE,stacktop,&thread_routine, reinterpret_cast<void*>(2));
int status = 0;
waitpid(child, &status, 0x0);
std::cout<<"return status 0x"<<std::hex<<status<<std::endl; // should return 0? but usually not
}