int main(int argc, char **argv) { srand(time(NULL)); pi = 4.0 * atan(1); min_x = 0.0; max_x = 3.0 * pi; if (argc > 1) { if (strcmp(argv[1], "-n") == 0) { no_random = 1; } else { print_usage(argv[0]); return 1; } } Table my_table = createMyTable(); Table doubled_table = doubleTable(&my_table, min_x); Table left_table = createTable(min_x, max_x, 0); Table middle_table = createTable(min_x, max_x, numof_parts / 2); Table right_table = createTable(min_x, max_x, numof_parts - 1); printReport(&my_table, "Initial table"); printReport(&doubled_table, "Doubled table"); printReport(&left_table, "Left table"); printReport(&middle_table, "Middle table"); printReport(&right_table, "Right table"); resetFunction(&right_table, my_g); resetFunction(&middle_table, my_g); resetFunction(&left_table, my_g); resetFunction(&doubled_table, my_g); resetFunction(&my_table, my_g); printReport(&my_table, "Initial table"); printReport(&doubled_table, "Doubled table"); printReport(&left_table, "Left table"); printReport(&middle_table, "Middle table"); printReport(&right_table, "Right table"); disposeTable(&right_table); disposeTable(&middle_table); disposeTable(&left_table); disposeTable(&doubled_table); disposeTable(&my_table); reportMaxError(); return 0; }
/* * ReceiveSharedInvalidMessages * Process shared-cache-invalidation messages waiting for this backend * * NOTE: it is entirely possible for this routine to be invoked recursively * as a consequence of processing inside the invalFunction or resetFunction. * Hence, we must be holding no SI resources when we call them. The only * bad side-effect is that SIDelExpiredDataEntries might be called extra * times on the way out of a nested call. */ void ReceiveSharedInvalidMessages( void (*invalFunction) (SharedInvalidationMessage *msg), void (*resetFunction) (void)) { SharedInvalidationMessage data; int getResult; bool gotMessage = false; for (;;) { /* * We can run SIGetDataEntry in parallel with other backends * running SIGetDataEntry for themselves, since each instance will * modify only fields of its own backend's ProcState, and no * instance will look at fields of other backends' ProcStates. We * express this by grabbing SInvalLock in shared mode. Note that * this is not exactly the normal (read-only) interpretation of a * shared lock! Look closely at the interactions before allowing * SInvalLock to be grabbed in shared mode for any other reason! * * The routines later in this file that use shared mode are okay with * this, because they aren't looking at the ProcState fields * associated with SI message transfer; they only use the * ProcState array as an easy way to find all the PGPROC * structures. */ LWLockAcquire(SInvalLock, LW_SHARED); getResult = SIGetDataEntry(shmInvalBuffer, MyBackendId, &data); LWLockRelease(SInvalLock); if (getResult == 0) break; /* nothing more to do */ if (getResult < 0) { /* got a reset message */ elog(DEBUG4, "cache state reset"); resetFunction(); } else { /* got a normal data message */ invalFunction(&data); } gotMessage = true; } /* If we got any messages, try to release dead messages */ if (gotMessage) { LWLockAcquire(SInvalLock, LW_EXCLUSIVE); SIDelExpiredDataEntries(shmInvalBuffer); LWLockRelease(SInvalLock); } }
/* * ReceiveSharedInvalidMessages * Process shared-cache-invalidation messages waiting for this backend * * NOTE: it is entirely possible for this routine to be invoked recursively * as a consequence of processing inside the invalFunction or resetFunction. * Hence, we must be holding no SI resources when we call them. The only * bad side-effect is that SIDelExpiredDataEntries might be called extra * times on the way out of a nested call. */ void ReceiveSharedInvalidMessages( void (*invalFunction) (SharedInvalidationMessage *msg), void (*resetFunction) (void)) { SharedInvalidationMessage data; int getResult; bool gotMessage = false; for (;;) { /* * We can discard any pending catchup event, since we will not exit * this loop until we're fully caught up. */ catchupInterruptOccurred = 0; /* * We can run SIGetDataEntry in parallel with other backends running * SIGetDataEntry for themselves, since each instance will modify only * fields of its own backend's ProcState, and no instance will look at * fields of other backends' ProcStates. We express this by grabbing * SInvalLock in shared mode. Note that this is not exactly the * normal (read-only) interpretation of a shared lock! Look closely at * the interactions before allowing SInvalLock to be grabbed in shared * mode for any other reason! */ LWLockAcquire(SInvalLock, LW_SHARED); getResult = SIGetDataEntry(shmInvalBuffer, MyBackendId, &data); LWLockRelease(SInvalLock); if (getResult == 0) break; /* nothing more to do */ if (getResult < 0) { /* got a reset message */ elog(DEBUG4, "cache state reset"); resetFunction(); } else { /* got a normal data message */ invalFunction(&data); } gotMessage = true; } /* If we got any messages, try to release dead messages */ if (gotMessage) { LWLockAcquire(SInvalLock, LW_EXCLUSIVE); SIDelExpiredDataEntries(shmInvalBuffer); LWLockRelease(SInvalLock); } }
/* * ReceiveSharedInvalidMessages * Process shared-cache-invalidation messages waiting for this backend * * We guarantee to process all messages that had been queued before the * routine was entered. It is of course possible for more messages to get * queued right after our last SIGetDataEntries call. * * NOTE: it is entirely possible for this routine to be invoked recursively * as a consequence of processing inside the invalFunction or resetFunction. * Furthermore, such a recursive call must guarantee that all outstanding * inval messages have been processed before it exits. This is the reason * for the strange-looking choice to use a statically allocated buffer array * and counters; it's so that a recursive call can process messages already * sucked out of sinvaladt.c. */ void ReceiveSharedInvalidMessages( void (*invalFunction) (SharedInvalidationMessage *msg), void (*resetFunction) (void)) { #define MAXINVALMSGS 32 static SharedInvalidationMessage messages[MAXINVALMSGS]; /* * We use volatile here to prevent bugs if a compiler doesn't realize that * recursion is a possibility ... */ static volatile int nextmsg = 0; static volatile int nummsgs = 0; /* Deal with any messages still pending from an outer recursion */ while (nextmsg < nummsgs) { SharedInvalidationMessage *msg = &messages[nextmsg++]; invalFunction(msg); } do { int getResult; nextmsg = nummsgs = 0; /* Try to get some more messages */ getResult = SIGetDataEntries(messages, MAXINVALMSGS); if (getResult < 0) { /* got a reset message */ elog(DEBUG4, "cache state reset"); resetFunction(); break; /* nothing more to do */ } /* Process them, being wary that a recursive call might eat some */ nextmsg = 0; nummsgs = getResult; while (nextmsg < nummsgs) { SharedInvalidationMessage *msg = &messages[nextmsg++]; invalFunction(msg); } /* * We only need to loop if the last SIGetDataEntries call (which might * have been within a recursive call) returned a full buffer. */ } while (nummsgs == MAXINVALMSGS); /* * We are now caught up. If we received a catchup signal, reset that * flag, and call SICleanupQueue(). This is not so much because we need * to flush dead messages right now, as that we want to pass on the * catchup signal to the next slowest backend. "Daisy chaining" the * catchup signal this way avoids creating spikes in system load for what * should be just a background maintenance activity. */ if (catchupInterruptOccurred) { catchupInterruptOccurred = 0; elog(DEBUG4, "sinval catchup complete, cleaning queue"); SICleanupQueue(false, 0); } }
void FitDialog::initEditPage() { QGridLayout *gl1 = new QGridLayout(); gl1->addWidget(new QLabel(tr("Category")), 0, 0); gl1->addWidget(new QLabel(tr("Function")), 0, 1); gl1->addWidget(new QLabel(tr("Expression")), 0, 2); categoryBox = new QListWidget(); categoryBox->addItem(tr("User defined")); categoryBox->addItem(tr("Built-in")); categoryBox->addItem(tr("Basic")); categoryBox->addItem(tr("Plugins")); gl1->addWidget(categoryBox, 1, 0); funcBox = new QListWidget(); gl1->addWidget(funcBox, 1, 1); explainBox = new QTextEdit(); explainBox->setReadOnly(true); gl1->addWidget(explainBox, 1, 2); boxUseBuiltIn = new QCheckBox(); boxUseBuiltIn->setText(tr("Fit with &built-in function")); boxUseBuiltIn->hide(); QHBoxLayout *hbox1 = new QHBoxLayout(); hbox1->addWidget(boxUseBuiltIn); hbox1->addStretch(); polynomOrderLabel = new QLabel( tr("Polynomial Order")); polynomOrderLabel->hide(); hbox1->addWidget(polynomOrderLabel); polynomOrderBox = new QSpinBox(); polynomOrderBox->setMinimum(1); polynomOrderBox->setValue(2); polynomOrderBox->hide(); connect(polynomOrderBox, SIGNAL(valueChanged(int)), this, SLOT(showExpression(int))); hbox1->addWidget(polynomOrderBox); buttonPlugins = new QPushButton(tr( "&Choose plugins folder..." ) ); hbox1->addWidget(buttonPlugins); buttonPlugins->hide(); buttonClearUsrList = new QPushButton(tr( "Clear user &list" ) ); hbox1->addWidget(buttonClearUsrList); buttonClearUsrList->hide(); QGridLayout *gl2 = new QGridLayout(); gl2->addWidget(new QLabel(tr("Name")), 0, 0); boxName = new QLineEdit(tr("user1")); gl2->addWidget(boxName, 0, 1); btnAddFunc = new QPushButton(tr( "&Save" )); gl2->addWidget(btnAddFunc, 0, 2); gl2->addWidget(new QLabel(tr("Parameters")), 1, 0); boxParam = new QLineEdit("a, b"); gl2->addWidget(boxParam, 1, 1); btnDelFunc = new QPushButton( tr( "&Remove" )); gl2->addWidget(btnDelFunc, 1, 2); QGroupBox *gb = new QGroupBox(); gb->setLayout(gl2); editBox = new QTextEdit(); editBox->setTextFormat(Qt::PlainText); editBox->setFocus(); QVBoxLayout *vbox1 = new QVBoxLayout(); btnAddTxt = new QPushButton(tr( "Add &expression" ) ); vbox1->addWidget(btnAddTxt); btnAddName = new QPushButton(tr( "Add &name" )); vbox1->addWidget(btnAddName); buttonClear = new QPushButton(tr( "Rese&t" )); vbox1->addWidget(buttonClear); buttonCancel2 = new QPushButton(tr( "&Close" )); vbox1->addWidget(buttonCancel2); btnContinue = new QPushButton(tr( "&Fit >>" )); vbox1->addWidget(btnContinue); vbox1->addStretch(); QHBoxLayout *hbox2 = new QHBoxLayout(); hbox2->addWidget(editBox); hbox2->addLayout(vbox1); QVBoxLayout *vbox2 = new QVBoxLayout(); vbox2->addLayout(gl1); vbox2->addLayout(hbox1); vbox2->addWidget(gb); vbox2->addLayout(hbox2); editPage = new QWidget(); editPage->setLayout(vbox2); tw->addWidget(editPage); connect( buttonPlugins, SIGNAL( clicked() ), this, SLOT(choosePluginsFolder())); connect( buttonClear, SIGNAL( clicked() ), this, SLOT(resetFunction())); connect( buttonClearUsrList, SIGNAL( clicked() ), this, SLOT(clearUserFunctions())); connect( categoryBox, SIGNAL(currentRowChanged (int)), this, SLOT(showFunctionsList(int) ) ); connect( funcBox, SIGNAL(currentRowChanged(int)), this, SLOT(showExpression(int))); connect( boxUseBuiltIn, SIGNAL(toggled(bool)), this, SLOT(setFunction(bool) ) ); connect( btnAddName, SIGNAL(clicked()), this, SLOT(pasteFunctionName() ) ); connect( btnAddTxt, SIGNAL(clicked()), this, SLOT(pasteExpression() ) ); connect( btnContinue, SIGNAL(clicked()), this, SLOT(showFitPage() ) ); connect( btnAddFunc, SIGNAL(clicked()), this, SLOT(saveUserFunction())); connect( btnDelFunc, SIGNAL(clicked()), this, SLOT(removeUserFunction())); connect( buttonCancel2, SIGNAL(clicked()), this, SLOT(close()) ); }