Why ZooKeeper needs to usleep in order to create persistent nodes - c++

I want to create persistent nodes in ZooKeeper. To do this, I have these two functions:
void create_completion(int rc, const char * value, const void * data){
// empty callback at this moment
}
void create(const char * path, const char * value){
zoo_acreate(zh, path, value, 0, &ZOO_OPEN_ACL_UNSAFE, 0, create_completion, NULL);
}
What I find interesting, is that if I call create function from my main function and then just terminate, then no data is uploaded:
int main(){
... some code to initialize session
create("/newnode", ""); // node is not created
zookeeper_close(zh);
return 0;
}
Whereas if I do:
int main(){
... some code to initialize session
create("/newnode", ""); // node is created
bool flag = true;
while(flag){
usleep(10000000);
flag = false;
}
zookeeper_close(zh);
return 0;
}
then "/newnode" is uploaded to ZooKeeper. So, what is wrong with that and why do I really need this loop?

Related

Retrieve ptr from function call asmjit

I am trying to generate a function call using AsmJit to which I pass an char*. This char* is in itself retrieved from another function call. I tried out this:
typedef
const char* getStr();
const char* getStrImpl() {
return "hello pie";
}
void use_str_impl(int id, const char* c_str) {
// do stuff...
}
int main() {
JitRuntime rt;
CodeHolder code;
code.init(rt.getCodeInfo());
X86Compiler c(&code);
auto jitted_func = c.addFunc(FuncSignature0<const char*>(code.getCodeInfo().getCdeclCallConv()));
auto err = c.getLastError();
auto call = c.call((uint64_t) fooFuncImpl, FuncSignature0<intptr_t>());
X86Gpd res(call->getRet().getId());
auto call2 = c.call((uint64_t) send_input, FuncSignature2<void, int, intptr_t>());
err = !call2->setArg(0, Imm(42));
err = !call2->setArg(1, res);
c.ret();
c.endFunc();
err = c.finalize();
if(err) return 0;
size_t size = code.getCodeSize();
VMemMgr vm;
void* p = vm.alloc(size);
if (!p) return 0;
code.relocate(p);
auto fun = (entrypoint*) p;
fun();
}
It turns out this does not generate any instructions for the second parameter or second call to setArg. I also tried to use .newIntPtr and using move instructions to move the result of call into place. But this generated dec and add instructions which made no sense to me and my small experience with assembly. What is the correct way of doing this type of thing?
Btw I am using the AsmJit next branch.
I have done few corrections to your sample with some comments.
Better Usage of JitRuntime:
JitRuntime rt;
size_t size = code.getCodeSize();
VMemMgr vm;
....
void* p = vm.alloc(size);
if (!p) return 0;
code.relocate(p);
auto fun = (entrypoint*) p;
You have used JitRuntime just to setup the parameters for CodeHolder, but then avoided it and allocated the memory for the function yourself. While that's a valid use case it's not what most people do. Using runtime's add() is sufficient in most cases.
Invalid use of CCFuncCall::getRet():
X86Gpd res(call->getRet().getId());
The call node at this point doesn't have any return register assigned so it would return an invalid id. If you need to create a virtual register you always have to call compiler's newSomething(). AsmJit's compiler provides API to check for that case at runtime, if you are unsure:
// Would print 0
printf("%d", (int)c.isVirtRegValid(call->getRet().getId()));
The solution is to create a new virtual register and ASSIGN it to the function's return value. Assigning return value requires an index (like assigning an argument), the reason is that some functions may return multiple values(like 64-bit value in 32-bit mode), using 0 as index is sufficient most of the time.
X86Gp reg = c.newIntPtr("reg");
call->setRet(0, reg);
You can verify getRet() functionality:
X86Gp reg = c.newIntPtr("reg");
assert(call->getRet(0).isNone());
call->setRet(0, reg);
assert(call->getRet(0) == reg);
Fully working example:
#include <stdio.h>
#include <asmjit/asmjit.h>
const char* func_a() {
printf("func_a(): Called\n");
return "hello pie";
}
void func_b(int id, const char* c_str) {
printf("func_b(%d, %s): Called\n", id, c_str);
}
int main() {
using namespace asmjit;
JitRuntime rt;
CodeHolder code;
code.init(rt.getCodeInfo());
X86Compiler c(&code);
X86Gp reg = c.newIntPtr("reg");
// Compilation step...
c.addFunc(FuncSignature0<void>(code.getCodeInfo().getCdeclCallConv()));
auto call_a = c.call((uint64_t)func_a, FuncSignature0<intptr_t>());
call_a->setRet(0, reg);
auto call_b = c.call((uint64_t)func_b, FuncSignature2<void, int, intptr_t>());
call_b->setArg(0, Imm(42));
call_b->setArg(1, reg);
c.ret();
c.endFunc();
// Finalize does the following:
// - allocates virtual registers
// - inserts prolog / epilog
// - assembles to CodeHolder
auto err = c.finalize();
if (err) {
printf("COMPILER FAILED: %s\b", DebugUtils::errorAsString(err));
return 1;
}
typedef void (*EntryPoint)(void);
EntryPoint entry;
// Adds function to the runtime. Should be freed by rt.release().
// Function is valid until the runtime is valid if not released.
err = rt.add(&entry, &code);
if (err) {
printf("RUNTIME FAILED: %s\b", DebugUtils::errorAsString(err));
return 1;
}
entry();
return 0;
}
I am trying to create a function that receives and returns a double. For the call method I used the approach with Mem. At the end I need to save the result in the variable xmm1.
I can't identify the error. The sine function is called correctly. But for the final assembler generation error occurs.
JitRuntime rt;
CodeHolder code;
code.init(rt.codeInfo());
asmjit::x86::Compiler cc(&code);
asmjit::x86::Gp reg = cc.newIntPtr("reg");
asmjit::Zone zonee(1024);
asmjit::ConstPool constPool(&zonee);
asmjit::Label constPoolLabel = cc.newLabel();
// Compilation step...
// c.addFunc(asmjit::FuncSignatureT<void>(code.codeInfo().getCdeclCallConv()));
cc.addFunc(asmjit::FuncSignatureT<void>());
auto call_a = cc.call((uint64_t)func_a, FuncSignatureT<intptr_t>());
call_a->setRet(0, reg);
auto call_b = cc.call((uint64_t)func_b, FuncSignatureT<void, int, intptr_t>());
call_b->setArg(0, Imm(42));
call_b->setArg(1, reg);
auto seno = [&](double value) {
size_t valueOffset;
double seno = static_cast<double_t>(std::sin(value));
cout << " seno " << seno << endl;
constPool.add(&seno, sizeof(double), valueOffset);
return asmjit::x86::ptr(constPoolLabel, valueOffset);
};
asmjit::x86::Mem mem;
double test = 180.5;
auto call_c = cc.call(seno(test), asmjit::FuncSignatureT<double_t>());
call_c->setArg(0, asmjit::Imm(test));
call_c->_setRet(0, mem);
cc.movsd(asmjit::x86::xmm1, mem);
cc.ret();
cc.endFunc();
// Finalize does the following:
// - allocates virtual registers
// - inserts prolog / epilog
// - assembles to CodeHolder
auto err = cc.finalize();
if (err) {
printf("COMPILER FAILED: %s\b", DebugUtils::errorAsString(err));
return;
}
typedef void (*EntryPoint)(void);
EntryPoint entry;
// Adds function to the runtime. Should be freed by rt.release().
// Function is valid until the runtime is valid if not released.
err = rt.add(&entry, &code);
if (err) {
printf("RUNTIME FAILED: %s\b", DebugUtils::errorAsString(err));
return;
}
entry();
return;
perhaps the memory object should relate to some memory address?
Mem mem = qword_ptr ((uint64_t) &test);

c++ pthreads and struct's corrupting data

I'm new to pthreads and having a hard time creating a thread with a struct and keeping it's data intact while re-casting it from a void pointer.
I've spent days searching around trying to find a reason for this and haven't had much luck. Out of my two structures (using two different threads) one re-casts correctly in the thread, but for whatever reason, the second doesn't.
Structs:
struct Arguments {
List linkedList;
Node node;
Arguments(){}
Arguments (List *newList, Node *newNode){
linkedList = *newList;
pcb = *newPCB;
}
};
struct ClockControl {
int counter = 0;
pthread_mutex_t lock;
};
Threads:
void *schedule(void *args){
//Arguments *newArgs = static_cast<Arguments*>(args); <-- Tried this, doesn't work either.
arguments *newArgs = (arguments *) args;
List tempList = (newArgs ->linkedList); //DATA HERE IS CORRUPTED/WRONG
Node tempNode = (newArgs ->node); //DATA HERE IS CORRUPTED/WRONG
cout << "Flagged" << Lendl;
return NULL;
}
void *clockTime(void *clock){
//This thread works fine
clockControl *newClock = (clockControl*) clock;
int localVariable = 0;
localVariable = (newClock -> counter);
pthread_mutex_lock(&(newClock -> lock));
localVariable++;
newClock->counter = localVariable;
pthread_mutex_unlock(&(newClock -> lock));
return NULL;
}
Main:
int main(int argc, char** argv)
{
pthread_t threads[NUM_THREADS]; //Defined as 5
clockControl clock;
clock.counter = 0;
pthread_mutex_init(&clock.lock, NULL);
//Lists are initialized with variables.
List pendingList = initializeList();
List readyList = initializeList();
Arguments *args = new Arguments(&readyList, &pendingList.head->info);
while (clock.counter < 6000){
pthread_create(&threads[1], NULL, clockTime, (void*) &clock);
if (clock.counter == pendingList.head->info.timeCreated){
pthread_create(&threads[0], NULL, schedule, (void*) &args);
//INSPECTING args HERE HAS ACCURATE DATA
}
//Clean up threads
for (int i = 0; i < 2; i++){
pthread_join(threads[i],NULL);
}
}
}
Like I said, I've searched around and pretty much spinning my wheels at this point. I have a suspicion it might be that the memory is being freed or cleaned up prior to the thread getting executed, but I can't find a way around it.
Any help would be appreciated.
You are passing the address of the pointer to args to your schedule function. When you use &args, args is already an Arguments* so you are passing an Arguments**. To solve this you can simply pass args by itself to the function.
Also just so you know, reinterpret_cast<Arguments*> is probably more appropriate than static_cast in this circumstance.
These two lines of code should be swapped
localVariable = (newClock -> counter);
pthread_mutex_lock(&(newClock -> lock)); z
i.e.
pthread_mutex_lock(&(newClock -> lock));
localVariable = (newClock -> counter);
So that localVariable will be the right value when more that one thread is reading the counter and updating it

Header functions

EDIT: by not working I mean that in my main array mA in main doesn't show any change to the elements within the array.
I have been checking my functions as I develop the headers and they have been working perfectly: Until I got to the final header MonitorArray.h.
mA.getScreen(i).checkScreen();
Didn't work and I couldn't work out why. So I created a new function within MonitorArray to do a similar job using the same function, and to my surprise it worked.
mA.pollScreens();
Which uses (Inside MonitorArray.h):
monitorArray[i].checkScreen();
Function getScreen:
ScreenArray MonitorArray::getScreen(int arrayPointer)
{
if (arrayPointer<0 || arrayPointer>=monitors)
{
return false;
}
else
{
return monitorArray[arrayPointer];
}
}
Function checkScreen and addArray:
void ScreenArray::checkScreen()
{
HDC dMonitor;
PixelArray pArray;
int lenX = 0, lenY = 0;
dMonitor = CreateDC(iMonitor.szDevice, iMonitor.szDevice, NULL, NULL);
lenX = (iMonitor.rcWork.right - iMonitor.rcWork.left) - 1;
lenY = (iMonitor.rcWork.bottom - iMonitor.rcWork.top) - 1;
pArray.setColour(0, GetPixel(dMonitor, 0, 0));
pArray...
...
...
addArray(&pArray);
ReleaseDC(NULL, dMonitor);
}
void ScreenArray::addArray(PixelArray* pA)
{
if (previousCheck(*pA))
{
arrayPosition = 0;
screenArray[arrayPosition] = *pA;
arrayPosition++;
}
else
{
screenArray[arrayPosition] = *pA;
arrayPosition++;
}
if (arrayPosition==11)
{
//Run screen saver on monitor
}
}
Why does running the command within the header file through a new function work but running the functions from main not?
Assuming that "didn't work" means "didn't affect the ScreenArray in my MonitorArray", it's because getScreen returns a copy of the array element
ScreenArray MonitorArray::getScreen(int arrayPointer)
while the new member function most likely works with the array directly.
You'll need to return a pointer to the array element instead:
ScreenArray* MonitorArray::getScreen(int arrayPointer)
{
if (arrayPointer<0 || arrayPointer>=monitors)
{
return NULL;
}
else
{
return &monitorArray[arrayPointer];
}
}
(BTW: the implicit conversion from bool to ScreenArray looks very odd.)

Run time Error - Stack around the variable arr_processes was corrupted

this code is make queues for the the operating system
I used structures to implement my processes
and used arr_processes to handle all of this processes
and new_processes array to sort this processes according to its arrival time
but when i run this code on visual studio 2010
it produces this run time error
Run-Time Check Failure #2 - Stack around the variable arr_processes was corrupted!
this is the code
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
int arr_time;
int serv_time;
int deadline;
} process;
void print_process(process n);
int main()
{
process arr_processes[8];
process new_processes[8];
process real_processes[3];
process ready_processes[5];
process tmp_process[1];
int length_ready;
int i,length,j;
int length_real;
arr_processes[0].id=1;
arr_processes[0].arr_time=12;
arr_processes[0].serv_time=4;
arr_processes[0].deadline=0;
arr_processes[1].id=2;
arr_processes[1].arr_time=10;
arr_processes[1].serv_time=5;
arr_processes[1].deadline=0;
arr_processes[2].id=3;
arr_processes[2].arr_time=9;
arr_processes[2].serv_time=2;
arr_processes[2].deadline=0;
arr_processes[3].id=4;
arr_processes[3].arr_time=8;
arr_processes[3].serv_time=4;
arr_processes[3].deadline=10;
arr_processes[4].id=5;
arr_processes[4].arr_time=5;
arr_processes[4].serv_time=2;
arr_processes[4].deadline=8;
arr_processes[5].id=6;
arr_processes[5].arr_time=3;
arr_processes[5].serv_time=3;
arr_processes[5].deadline=0;
arr_processes[6].id=7;
arr_processes[6].arr_time=2;
arr_processes[6].serv_time=3;
arr_processes[6].deadline=0;
arr_processes[7].id=8;
arr_processes[7].arr_time=1;
arr_processes[7].serv_time=1;
arr_processes[7].deadline=28;
length=sizeof(arr_processes)/sizeof(arr_processes[0]);
printf("\t length of the processes=%i\n\n",length);
printf("\t The Original processes \n\n");
for(i=0;i<8;i++)
print_process(arr_processes[i]);
// now we want to sort the processes according to their arrival time
for(i=0;i<8;i++)
{
new_processes[i]=arr_processes[i];
}
for(i=0;i<length;i++)
{
for(j=0;j<length-i;j++)
{
if((new_processes[j].arr_time)>(new_processes[j+1].arr_time))
{
tmp_process[0]=new_processes[j];
new_processes[j]=new_processes[j+1];
new_processes[j+1]=tmp_process[0];
}
}
}
printf("\t The New processes \n\n");
for(i=0;i<8;i++)
print_process(new_processes[i]); // the new queue
ready_processes[0]=arr_processes[0];
ready_processes[1]=arr_processes[1];
ready_processes[2]=arr_processes[2];
ready_processes[3]=arr_processes[5];
ready_processes[4]=arr_processes[6];
length_ready=sizeof(ready_processes)/sizeof(ready_processes[0]);
// now we want to design the ready queue
for(i=0;i<length_ready;i++)
{
for(j=0;j<length_ready-i;j++)
{
if((ready_processes[j].arr_time)>ready_processes[j+1].arr_time)
{
tmp_process[0]=ready_processes[j];
ready_processes[j]=ready_processes[j+1];
ready_processes[j+1]=tmp_process[0];
}
}
}
printf("\t The ready processes \n\n");
for(i=0;i<length_ready;i++)
print_process(ready_processes[i]); // the ready queue
// now we want to design the ready real queue for the shortest deadline first
// we donnot need to check for the new proesses at each instant of time
//but we need to check for the service time from now
real_processes[0]=arr_processes[3];
real_processes[1]=arr_processes[4];
real_processes[2]=arr_processes[7];
length_real=sizeof(real_processes)/sizeof(real_processes[0]);
for(i=0;i<length_real;i++)
{
for(j=0;j<length_real-i;j++)
{
if((real_processes[j].deadline)>real_processes[j+1].deadline)
{
tmp_process[0]=real_processes[j];
real_processes[j]=real_processes[j+1];
real_processes[j+1]=tmp_process[0];
}
}
}
printf("\t The real processes \n\n");
for(i=0;i<length_real;i++)
print_process(real_processes[i]); // the ready real queue
// removed real process
process removed_real;
removed_real.id=0;
removed_real.arr_time=0;
removed_real.serv_time=0;
removed_real.deadline=0;
process running_process;
running_process.id=0;
running_process.arr_time=0;
running_process.serv_time=0;
running_process.deadline=0;
int counter=0;
int start_time;
while(counter<=28)
{
printf("when time = %i\n\n",counter);
// printf("\t The real processes when the counter=%i \n\n",counter);
// for(i=0;i<length_real;i++)
// print_process(real_processes[i]); // the ready real queue
// first we must check for the real processes
for(i=0;i<length_real;i++)
{
if((counter==real_processes[i].arr_time)
&&((real_processes[i].deadline)-counter)>=(real_processes[i].serv_time))
{
running_process=real_processes[i];
printf("The non zero deadline process is:%i\n",running_process.id);
real_processes[i]=removed_real;
start_time=counter; // real process
while(counter!=(start_time+running_process.serv_time))
{
printf("At time = %i,The Running Process is...\n",counter);
print_process(running_process);
counter++;
}
}
}
counter++;
}
return 0;
}
void print_process(process n)
{
if(n.deadline!=0)
printf("ID=%i\narr_time=%i\nserv_time=%i\ndeadline=%i\n\n\n",n.id,n.arr_time,n.serv_time,n.deadline);
else if(n.deadline==0)
printf("ID=%i\narr_time=%i\nserv_time=%i\n\n\n",n.id,n.arr_time,n.serv_time);
}
As you run out of index, here is a sort example:
for(i=0; i<length - 1; i++)
{
for(j=i + 1;j<length;j++)
{
if((new_processes[j].arr_time)>(new_processes[i].arr_time))
{
tmp_process[0]=new_processes[j];
new_processes[j]=new_processes[i] ;
new_processes[i]=tmp_process[0] ;
}
}
}
Or, you can use standard function:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
Define a comparison function:
int compare_by_arr_time(const void* a, const void* b)
{
int a_int = ((const process*)a)->arr_time;
int b_int = ((const process*)b)->arr_time;
return a_int - b_int; // or b_int - a_int
}
And use it as follows:
qsort(new_processes,
sizeof(new_processes)/sizeof(new_processes[0]),
sizeof(new_processes[0]),
compare_by_arr_time);
You get these kinds of errors when you go out of the bounds of an array.
for(i=0;i<length;i++)
{
for(j=0;j<length-i;j++)
{
if((new_processes[j].arr_time)>(new_processes[j+1].arr_time))
{
tmp_process[0]=new_processes[j];
new_processes[j]=new_processes[j+1] ;
new_processes[j+1]=tmp_process[0] ;
}
}
}
In the first iteration, i = 0, j = 0 and j must be less than 8 - i, which is 8.
Notice the expression j+1. This expression will return values in the range of [1 ... 9] during the first iteration of the outer-most loop, and thus, you will be going out of the bounds your new_processes array.
There's your problem.
edit: This problem may also be present in the for loops that follow the first one.

storing struct as value using CFDictionarySetValue()

Iam new to using Core Foundations. I want to use dictionary to store some key value pair. The value must be a pointer to a struct. This pointer is pointing to dynamically allocated buffer.
CFMutableDictionaryRef init_hash_table() {
return CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
This is used to create the dictionary and the return value is stored as global variable.
CFNumberRef
create_hash_key(int sd) {
return CFNumberCreate(NULL, kCFNumberIntType, &sd);
}
int
add_hash_entry(CFMutableDictionaryRef dict, int sd, void *pkt) {
CFNumberRef key = create_hash_key(sd);
CFDictionarySetValue(dict, key, pkt);
return 0;
}
When I execute this code, I get segfault. I see that pkt has a valid address and key seems to be created. Does anyone know how to assign a pointer to value part?
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000011
0x00007fff8c9f339f in objc_msgSend_fixup ()
Any ideas?
The problem is the kCFTypeDictionaryValueCallBacks argument. From the documentation:
kCFTypeDictionaryValueCallBacks
Predefined CFDictionaryValueCallBacks structure containing a set of
callbacks appropriate for use when the values in a CFDictionary are
all CFType-derived objects.
So in your case, CFRetain() is called on the pointer when the value is added to the
dictionary. This causes the crash because the pointer does not point to a CoreFoundation
object.
You can create the dictionary with
CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
instead, so that no "reference counting" will be done on the value.
Alternatively, you can wrap the pointer into a CFDataRef and put that into the
dictionary.
In both cases it is your responsibility that the pointer is still valid
when the value is retrieved from the dictionary later.
Here is a simple example how you could implement refcounting for your custom objects:
typedef struct {
int refcount;
int val;
} mystruct;
const void *myretain(CFAllocatorRef allocator, const void *value)
{
mystruct *p = (mystruct *)value;
p->refcount++;
return p;
}
void myrelease(CFAllocatorRef allocator, const void *value)
{
mystruct *p = (mystruct *)value;
if (p->refcount == 1)
free(p);
else
p->refcount--;
}
int main(int argc, const char * argv[])
{
mystruct *p = malloc(sizeof(*p));
p->refcount = 1;
p->val = 13;
CFDictionaryValueCallBacks vcb = { 0 , myretain, myrelease, NULL, NULL };
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &vcb);
int sd = 13;
CFNumberRef key = CFNumberCreate(NULL, kCFNumberIntType, &sd);
CFDictionarySetValue(dict, key, p);
// refcount == 2
myrelease(NULL, p);
// refcount == 1
mystruct *q = CFDictionaryGetValue(dict, key);
// refcount is still 1, "GetValue" does not increment the refcount
CFRelease(dict);
// object is deallocated
return 0;
}