/** * Transaction 2 - T2 * * Read from Subscriber: * * Input: * SubscriberNumber * * Output: * Location * Changed by * Changed Timestamp * Name */ void start_T2(Ndb * pNDB, ThreadData * td, int async) { DEBUG3("T2(%.*s, %d): - Starting", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.location); NdbConnection * pCON = 0; while((pCON = startTransaction(pNDB, td)) == 0) { CHECK_ALLOWED_ERROR("T2-1: startTransaction", td, pNDB->getNdbError()); NdbSleep_MilliSleep(10); } if (td->ndbRecordSharedData) { char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> subscriberTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_SUBSCRIBER_LOCATION); SET_MASK(mask, IND_SUBSCRIBER_CHANGED_BY); SET_MASK(mask, IND_SUBSCRIBER_CHANGED_TIME); SET_MASK(mask, IND_SUBSCRIBER_NAME); const NdbOperation* MyOp= pCON->readTuple(record, rowPtr, record, rowPtr, NdbOperation::LM_Read, mask); CHECK_NULL((void*) MyOp, "T2: readTuple", td, pCON->getNdbError()); } else { NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOp, "T2: getNdbOperation", td, pCON->getNdbError()); MyOp->readTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->getValue(IND_SUBSCRIBER_LOCATION, (char *)&td->transactionData.location); MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, td->transactionData.changed_by); MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, td->transactionData.changed_time); MyOp->getValue(IND_SUBSCRIBER_NAME, td->transactionData.name); } if (async == 1) { pCON->executeAsynchPrepare( Commit , T2_Callback, td); } else { int result = pCON->execute(Commit); T2_Callback(result, pCON, (void*)td); return; }//if }
void setAltFunct(GPIO_t* port, GPIO_PIN_t pin, GPIO_AFR_t af) { if(pin <= 7) { SET_MASK( port->AFRL, (GPIO_AFR_AFR_bm << (pin * 4)), (af << (pin * 4))); } else { SET_MASK( port->AFRH, (GPIO_AFR_AFR_bm << (pin * 4)), (af << ((pin - 8) * 4))); } }
/* CPU affinity mask buffer instead, as the present code will fail beyond 32 CPUs */ int set_cpu_affinity(unsigned int cpuid) { unsigned long mask = 0xffffffff; unsigned int len = sizeof(mask); int retValue = 0; int pid; #ifdef _WIN32 HANDLE hProcess; #endif #ifdef _WIN32 SET_MASK(cpuid) hProcess = GetCurrentProcess(); if (SetProcessAffinityMask(hProcess, mask) == 0) { return -1; } #elif CMK_HAS_BINDPROCESSOR pid = getpid(); if (bindprocessor(BINDPROCESS, pid, cpuid) == -1) return -1; #else #ifdef CPU_ALLOC if ( cpuid >= CPU_SETSIZE ) { cpu_set_t *cpusetp; size_t size; int num_cpus; num_cpus = cpuid + 1; cpusetp = CPU_ALLOC(num_cpus); if (cpusetp == NULL) { perror("set_cpu_affinity CPU_ALLOC"); return -1; } size = CPU_ALLOC_SIZE(num_cpus); CPU_ZERO_S(size, cpusetp); CPU_SET_S(cpuid, size, cpusetp); if (sched_setaffinity(0, size, cpusetp) < 0) { perror("sched_setaffinity dynamically allocated"); CPU_FREE(cpusetp); return -1; } CPU_FREE(cpusetp); } else #endif { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(cpuid, &cpuset); /*SET_MASK(cpuid)*/ /* PID 0 refers to the current process */ /*if (sched_setaffinity(0, len, &mask) < 0) {*/ if (sched_setaffinity(0, sizeof(cpuset), &cpuset) < 0) { perror("sched_setaffinity"); return -1; } } #endif return 0; }
void T5_Callback_1(int result, NdbConnection * pCON, void * threadData) { ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T5-1: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T5(td->pNDB, td, stat_async); return; }//if DEBUG3("T5(%.*s, %.2d): - Callback 1", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id); if (td->ndbRecordSharedData) { char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> groupTableAllowDeleteNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_GROUP_ALLOW_DELETE); const NdbOperation* MyOp= pCON->readTuple(record, rowPtr, record, rowPtr, NdbOperation::LM_Read, mask); CHECK_NULL((void*)MyOp, "T5-2: readTuple", td, pCON->getNdbError()); } else { NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); CHECK_NULL(MyOp, "T5-2: getNdbOperation", td, pCON->getNdbError()); MyOp->readTuple(); MyOp->equal(IND_GROUP_ID, (char*)&td->transactionData.group_id); MyOp->getValue(IND_GROUP_ALLOW_DELETE, (char *)&td->transactionData.permission); } if (stat_async == 1) { pCON->executeAsynchPrepare( NoCommit , T5_Callback_2, td); } else { int result = pCON->execute( NoCommit ); T5_Callback_2(result, pCON, (void*)td); return; }//if }
DEVICE_READ32_SWITCH() { case NV_PFIFO_RAMHT: result = 0x03000100; // = NV_PFIFO_RAMHT_SIZE_4K | NV_PFIFO_RAMHT_BASE_ADDRESS(NumberOfPaddingBytes >> 12) | NV_PFIFO_RAMHT_SEARCH_128 break; case NV_PFIFO_RAMFC: result = 0x00890110; // = ? | NV_PFIFO_RAMFC_SIZE_2K | ? break; case NV_PFIFO_INTR_0: result = d->pfifo.pending_interrupts; break; case NV_PFIFO_INTR_EN_0: result = d->pfifo.enabled_interrupts; break; case NV_PFIFO_RUNOUT_STATUS: result = NV_PFIFO_RUNOUT_STATUS_LOW_MARK; /* low mark empty */ break; case NV_PFIFO_CACHE1_PUSH0: result = d->pfifo.cache1.push_enabled; break; case NV_PFIFO_CACHE1_PUSH1: SET_MASK(result, NV_PFIFO_CACHE1_PUSH1_CHID, d->pfifo.cache1.channel_id); SET_MASK(result, NV_PFIFO_CACHE1_PUSH1_MODE, d->pfifo.cache1.mode); break; case NV_PFIFO_CACHE1_STATUS: { qemu_mutex_lock(&d->pfifo.cache1.cache_lock); if (d->pfifo.cache1.cache.empty()) { result |= NV_PFIFO_CACHE1_STATUS_LOW_MARK; /* low mark empty */ } qemu_mutex_unlock(&d->pfifo.cache1.cache_lock); break; } case NV_PFIFO_CACHE1_DMA_PUSH: SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS, d->pfifo.cache1.dma_push_enabled); SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_STATUS, d->pfifo.cache1.dma_push_suspended); SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_BUFFER, 1); /* buffer emoty */ break; case NV_PFIFO_CACHE1_DMA_STATE: SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE, d->pfifo.cache1.method_nonincreasing); SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_METHOD, d->pfifo.cache1.method >> 2); SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL, d->pfifo.cache1.subchannel); SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT, d->pfifo.cache1.method_count); SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_ERROR, d->pfifo.cache1.error); break; case NV_PFIFO_CACHE1_DMA_INSTANCE: SET_MASK(result, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK, d->pfifo.cache1.dma_instance >> 4); break; case NV_PFIFO_CACHE1_DMA_PUT: result = d->user.channel_control[d->pfifo.cache1.channel_id].dma_put; break; case NV_PFIFO_CACHE1_DMA_GET: result = d->user.channel_control[d->pfifo.cache1.channel_id].dma_get; break; case NV_PFIFO_CACHE1_DMA_SUBROUTINE: result = d->pfifo.cache1.subroutine_return | (xbaddr)d->pfifo.cache1.subroutine_active; break; case NV_PFIFO_CACHE1_PULL0: { qemu_mutex_lock(&d->pfifo.cache1.cache_lock); result = d->pfifo.cache1.pull_enabled; qemu_mutex_unlock(&d->pfifo.cache1.cache_lock); break; } case NV_PFIFO_CACHE1_ENGINE: { qemu_mutex_lock(&d->pfifo.cache1.cache_lock); for (int i = 0; i < NV2A_NUM_SUBCHANNELS; i++) { result |= d->pfifo.cache1.bound_engines[i] << (i * 2); } qemu_mutex_unlock(&d->pfifo.cache1.cache_lock); break; } case NV_PFIFO_CACHE1_DMA_DCOUNT: result = d->pfifo.cache1.dcount; break; case NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW: result = d->pfifo.cache1.get_jmp_shadow; break; case NV_PFIFO_CACHE1_DMA_RSVD_SHADOW: result = d->pfifo.cache1.rsvd_shadow; break; case NV_PFIFO_CACHE1_DMA_DATA_SHADOW: result = d->pfifo.cache1.data_shadow; break; default: DEVICE_READ32_REG(pfifo); // Was : DEBUG_READ32_UNHANDLED(PFIFO); break; }
static void pfifo_run_puller(NV2AState *d) { uint32_t *pull0 = &d->pfifo.regs[NV_PFIFO_CACHE1_PULL0]; uint32_t *pull1 = &d->pfifo.regs[NV_PFIFO_CACHE1_PULL1]; uint32_t *engine_reg = &d->pfifo.regs[NV_PFIFO_CACHE1_ENGINE]; uint32_t *status = &d->pfifo.regs[NV_PFIFO_CACHE1_STATUS]; uint32_t *get_reg = &d->pfifo.regs[NV_PFIFO_CACHE1_GET]; uint32_t *put_reg = &d->pfifo.regs[NV_PFIFO_CACHE1_PUT]; // TODO // CacheEntry working_cache[NV2A_CACHE1_SIZE]; // int working_cache_size = 0; // pull everything into our own queue // TODO think more about locking while (true) { if (!GET_MASK(*pull0, NV_PFIFO_CACHE1_PULL0_ACCESS)) return; /* empty cache1 */ if (*status & NV_PFIFO_CACHE1_STATUS_LOW_MARK) break; uint32_t get = *get_reg; uint32_t put = *put_reg; assert(get < 128*4 && (get % 4) == 0); uint32_t method_entry = d->pfifo.regs[NV_PFIFO_CACHE1_METHOD + get*2]; uint32_t parameter = d->pfifo.regs[NV_PFIFO_CACHE1_DATA + get*2]; uint32_t new_get = (get+4) & 0x1fc; *get_reg = new_get; if (new_get == put) { // set low mark *status |= NV_PFIFO_CACHE1_STATUS_LOW_MARK; } if (*status & NV_PFIFO_CACHE1_STATUS_HIGH_MARK) { // unset high mark *status &= ~NV_PFIFO_CACHE1_STATUS_HIGH_MARK; // signal pusher qemu_cond_signal(&d->pfifo.pusher_cond); } uint32_t method = method_entry & 0x1FFC; uint32_t subchannel = GET_MASK(method_entry, NV_PFIFO_CACHE1_METHOD_SUBCHANNEL); // NV2A_DPRINTF("pull %d 0x%x 0x%x - subch %d\n", get/4, method_entry, parameter, subchannel); if (method == 0) { RAMHTEntry entry = ramht_lookup(d, parameter); assert(entry.valid); // assert(entry.channel_id == state->channel_id); assert(entry.engine == ENGINE_GRAPHICS); /* the engine is bound to the subchannel */ assert(subchannel < 8); SET_MASK(*engine_reg, 3 << (4*subchannel), entry.engine); SET_MASK(*pull1, NV_PFIFO_CACHE1_PULL1_ENGINE, entry.engine); // NV2A_DPRINTF("engine_reg1 %d 0x%x\n", subchannel, *engine_reg); // TODO: this is f****d qemu_mutex_lock(&d->pgraph.lock); //make pgraph busy qemu_mutex_unlock(&d->pfifo.lock); pgraph_context_switch(d, entry.channel_id); pgraph_wait_fifo_access(d); pgraph_method(d, subchannel, 0, entry.instance); // make pgraph not busy qemu_mutex_unlock(&d->pgraph.lock); qemu_mutex_lock(&d->pfifo.lock); } else if (method >= 0x100) { // method passed to engine /* methods that take objects. * TODO: Check this range is correct for the nv2a */ if (method >= 0x180 && method < 0x200) { //qemu_mutex_lock_iothread(); RAMHTEntry entry = ramht_lookup(d, parameter); assert(entry.valid); // assert(entry.channel_id == state->channel_id); parameter = entry.instance; //qemu_mutex_unlock_iothread(); } enum FIFOEngine engine = GET_MASK(*engine_reg, 3 << (4*subchannel)); // NV2A_DPRINTF("engine_reg2 %d 0x%x\n", subchannel, *engine_reg); assert(engine == ENGINE_GRAPHICS); SET_MASK(*pull1, NV_PFIFO_CACHE1_PULL1_ENGINE, engine); // TODO: this is f****d qemu_mutex_lock(&d->pgraph.lock); //make pgraph busy qemu_mutex_unlock(&d->pfifo.lock); pgraph_wait_fifo_access(d); pgraph_method(d, subchannel, method, parameter); // make pgraph not busy qemu_mutex_unlock(&d->pgraph.lock); qemu_mutex_lock(&d->pfifo.lock); } else { assert(false); } } }
static void pfifo_run_pusher(NV2AState *d) { uint32_t *push0 = &d->pfifo.regs[NV_PFIFO_CACHE1_PUSH0]; uint32_t *push1 = &d->pfifo.regs[NV_PFIFO_CACHE1_PUSH1]; uint32_t *dma_subroutine = &d->pfifo.regs[NV_PFIFO_CACHE1_DMA_SUBROUTINE]; uint32_t *dma_state = &d->pfifo.regs[NV_PFIFO_CACHE1_DMA_STATE]; uint32_t *dma_push = &d->pfifo.regs[NV_PFIFO_CACHE1_DMA_PUSH]; uint32_t *dma_get = &d->pfifo.regs[NV_PFIFO_CACHE1_DMA_GET]; uint32_t *dma_put = &d->pfifo.regs[NV_PFIFO_CACHE1_DMA_PUT]; uint32_t *dma_dcount = &d->pfifo.regs[NV_PFIFO_CACHE1_DMA_DCOUNT]; uint32_t *status = &d->pfifo.regs[NV_PFIFO_CACHE1_STATUS]; uint32_t *get_reg = &d->pfifo.regs[NV_PFIFO_CACHE1_GET]; uint32_t *put_reg = &d->pfifo.regs[NV_PFIFO_CACHE1_PUT]; if (!GET_MASK(*push0, NV_PFIFO_CACHE1_PUSH0_ACCESS)) return; if (!GET_MASK(*dma_push, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS)) return; /* suspended */ if (GET_MASK(*dma_push, NV_PFIFO_CACHE1_DMA_PUSH_STATUS)) return; // TODO: should we become busy here?? // NV_PFIFO_CACHE1_DMA_PUSH_STATE _BUSY unsigned int channel_id = GET_MASK(*push1, NV_PFIFO_CACHE1_PUSH1_CHID); /* Channel running DMA mode */ uint32_t channel_modes = d->pfifo.regs[NV_PFIFO_MODE]; assert(channel_modes & (1 << channel_id)); assert(GET_MASK(*push1, NV_PFIFO_CACHE1_PUSH1_MODE) == NV_PFIFO_CACHE1_PUSH1_MODE_DMA); /* We're running so there should be no pending errors... */ assert(GET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_ERROR) == NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE); hwaddr dma_instance = GET_MASK(d->pfifo.regs[NV_PFIFO_CACHE1_DMA_INSTANCE], NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS) << 4; hwaddr dma_len; uint8_t *dma = nv_dma_map(d, dma_instance, &dma_len); while (true) { uint32_t dma_get_v = *dma_get; uint32_t dma_put_v = *dma_put; if (dma_get_v == dma_put_v) break; if (dma_get_v >= dma_len) { assert(false); SET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_ERROR, NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION); break; } uint32_t word = ldl_le_p((uint32_t*)(dma + dma_get_v)); dma_get_v += 4; uint32_t method_type = GET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE); uint32_t method_subchannel = GET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL); uint32_t method = GET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_METHOD) << 2; uint32_t method_count = GET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT); uint32_t subroutine_state = GET_MASK(*dma_subroutine, NV_PFIFO_CACHE1_DMA_SUBROUTINE_STATE); if (method_count) { /* full */ if (*status & NV_PFIFO_CACHE1_STATUS_HIGH_MARK) return; /* data word of methods command */ d->pfifo.regs[NV_PFIFO_CACHE1_DMA_DATA_SHADOW] = word; uint32_t put = *put_reg; uint32_t get = *get_reg; assert((method & 3) == 0); uint32_t method_entry = 0; SET_MASK(method_entry, NV_PFIFO_CACHE1_METHOD_ADDRESS, method >> 2); SET_MASK(method_entry, NV_PFIFO_CACHE1_METHOD_TYPE, method_type); SET_MASK(method_entry, NV_PFIFO_CACHE1_METHOD_SUBCHANNEL, method_subchannel); // NV2A_DPRINTF("push %d 0x%x 0x%x - subch %d\n", put/4, method_entry, word, method_subchannel); assert(put < 128*4 && (put%4) == 0); d->pfifo.regs[NV_PFIFO_CACHE1_METHOD + put*2] = method_entry; d->pfifo.regs[NV_PFIFO_CACHE1_DATA + put*2] = word; uint32_t new_put = (put+4) & 0x1fc; *put_reg = new_put; if (new_put == get) { // set high mark *status |= NV_PFIFO_CACHE1_STATUS_HIGH_MARK; } if (*status & NV_PFIFO_CACHE1_STATUS_LOW_MARK) { // unset low mark *status &= ~NV_PFIFO_CACHE1_STATUS_LOW_MARK; // signal puller qemu_cond_signal(&d->pfifo.puller_cond); } if (method_type == NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE_INC) { SET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_METHOD, (method + 4) >> 2); } SET_MASK(*dma_state, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT, method_count - 1); (*dma_dcount)++; } else {
void setPinOutType(GPIO_t* port, GPIO_PIN_t pin, GPIO_OTYPER_t type) { SET_MASK(port->OTYPER, (GPIO_OTYPER_OT0_bm << pin), (type << pin)); }
void setPinMode(GPIO_t* port, GPIO_PIN_t pin, GPIO_MODER_t mode) { SET_MASK( port->MODER, (GPIO_MODER_MODER0_bm << (pin * 2)), (mode << (pin * 2))); }
void setPinPull(GPIO_t* port, GPIO_PIN_t pin, GPIO_PUPDR_t pull) { SET_MASK( port->PUPDR, (GPIO_PUPDR_PUPDR0_bm << (pin * 2)), (pull << (pin * 2))); }
void setPinOutSpeed(GPIO_t* port, GPIO_PIN_t pin, GPIO_OSPEEDR_t speed) { SET_MASK( port->OSPEEDR, (GPIO_OSPEEDR_OSPEEDR0_bm << (pin * 2)), (speed << (pin * 2))); }
/** * Transaction 5 - T5 * * Delete session * * Input: * SubscriberNumber * ServerId * ServerBit * DoRollback * Output: * ChangedBy * ChangedTime * Location * BranchExecuted */ void start_T5(Ndb * pNDB, ThreadData * td, int async) { DEBUG3("T5(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id); NdbConnection * pCON = 0; while((pCON = startTransaction(pNDB, td)) == 0) { CHECK_ALLOWED_ERROR("T5-1: startTransaction", td, pNDB->getNdbError()); NdbSleep_MilliSleep(10); } if (td->ndbRecordSharedData) { char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> subscriberTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_SUBSCRIBER_LOCATION); SET_MASK(mask, IND_SUBSCRIBER_CHANGED_BY); SET_MASK(mask, IND_SUBSCRIBER_CHANGED_TIME); SET_MASK(mask, IND_SUBSCRIBER_GROUP); SET_MASK(mask, IND_SUBSCRIBER_SESSIONS); const NdbOperation* MyOp= pCON->readTuple(record, rowPtr, record, rowPtr, NdbOperation::LM_Read, mask); CHECK_NULL((void*)MyOp, "T5-1: readTuple", td, pCON->getNdbError()); m= 0; /* Create program to subtract something from the * subscriber sessions column */ Uint32 codeBuf[20]; NdbInterpretedCode program(pNDB->getDictionary()-> getTable(SUBSCRIBER_TABLE), codeBuf, 20); if (program.sub_val(IND_SUBSCRIBER_SESSIONS, (uint32)td->transactionData.server_bit) || program.interpret_exit_ok() || program.finalise()) { CHECK_NULL(NULL , "T5: Program create failed", td, program.getNdbError()); } NdbOperation::OperationOptions opts; opts.optionsPresent= NdbOperation::OperationOptions::OO_INTERPRETED; opts.interpretedCode= &program; MyOp= pCON->updateTuple(record, rowPtr, record, rowPtr, mask, &opts, sizeof(opts)); CHECK_NULL((void*)MyOp, "T5-1: updateTuple", td, pCON->getNdbError()); } else { /* Use old Api */ if (td->useCombinedUpdate) { NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOp, "T5-1: getNdbOperation", td, pCON->getNdbError()); MyOp->interpretedUpdateTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->getValue(IND_SUBSCRIBER_LOCATION, (char *)&td->transactionData.location); MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, td->transactionData.changed_by); MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, td->transactionData.changed_time); MyOp->getValue(IND_SUBSCRIBER_GROUP, (char *)&td->transactionData.group_id); MyOp->getValue(IND_SUBSCRIBER_SESSIONS, (char *)&td->transactionData.sessions); MyOp->subValue(IND_SUBSCRIBER_SESSIONS, (uint32)td->transactionData.server_bit); } else { /* Use separate read and update operations * This relies on execution ordering between operations on * the same row */ NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOp, "T5-1: getNdbOperation (readTuple)", td, pCON->getNdbError()); MyOp->readTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->getValue(IND_SUBSCRIBER_LOCATION, (char *)&td->transactionData.location); MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, td->transactionData.changed_by); MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, td->transactionData.changed_time); MyOp->getValue(IND_SUBSCRIBER_GROUP, (char *)&td->transactionData.group_id); MyOp->getValue(IND_SUBSCRIBER_SESSIONS, (char *)&td->transactionData.sessions); MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); CHECK_NULL(MyOp, "T5-1: getNdbOperation (updateTuple)", td, pCON->getNdbError()); MyOp->interpretedUpdateTuple(); MyOp->equal(IND_SUBSCRIBER_NUMBER, td->transactionData.number); MyOp->subValue(IND_SUBSCRIBER_SESSIONS, (uint32)td->transactionData.server_bit); } } stat_async = async; if (async == 1) { pCON->executeAsynchPrepare( NoCommit , T5_Callback_1, td); } else { int result = pCON->execute( NoCommit ); T5_Callback_1(result, pCON, (void*)td); return; }//if }
void T4_Callback_2(int result, NdbConnection * pCON, void * threadData) { ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T4-2: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T4(td->pNDB, td, stat_async); return; }//if Uint32 permission = td->transactionData.permission; Uint32 sessions = td->transactionData.sessions; Uint32 server_bit = td->transactionData.server_bit; if(((permission & server_bit) == server_bit) && ((sessions & server_bit) == 0)) { memcpy(td->transactionData.suffix, &td->transactionData.number[SFX_START], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, SUBSCRIBER_NUMBER_SUFFIX_LENGTH, td->transactionData.suffix); /* Operations 3 + 4 */ if (td->ndbRecordSharedData) { char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> sessionTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_SESSION_SUBSCRIBER); SET_MASK(mask, IND_SESSION_SERVER); SET_MASK(mask, IND_SESSION_DATA); const NdbOperation* MyOp= pCON->insertTuple(record, rowPtr, mask); CHECK_NULL((void*)MyOp, "T4-3: insertTuple", td, pCON->getNdbError()); record= td->ndbRecordSharedData-> serverTableNdbRecord; m= 0; NdbOperation::OperationOptions opts; opts.optionsPresent= NdbOperation::OperationOptions::OO_INTERPRETED; opts.interpretedCode= td->ndbRecordSharedData->incrServerInsertsProg; MyOp= pCON->updateTuple(record, rowPtr, record, rowPtr, mask, &opts, sizeof(opts)); CHECK_NULL((void*)MyOp, "T4-3: updateTuple", td, pCON->getNdbError()); } else { NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOp, "T4-3: getNdbOperation", td, pCON->getNdbError()); MyOp->insertTuple(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); MyOp->setValue(IND_SESSION_DATA, (char *)td->transactionData.session_details); /* Operation 4 */ /* Operation 5 */ MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T4-5: getNdbOperation", td, pCON->getNdbError()); MyOp->interpretedUpdateTuple(); MyOp->equal(IND_SERVER_ID, (char*)&td->transactionData.server_id); MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)td->transactionData.suffix); MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); } td->transactionData.branchExecuted = 1; } else { td->transactionData.branchExecuted = 0; DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, ((permission & server_bit) ? "permission - " : "no permission - "), ((sessions & server_bit) ? "in session - " : "no in session - ")); } if(!td->transactionData.do_rollback && td->transactionData.branchExecuted) { if (stat_async == 1) { pCON->executeAsynchPrepare( Commit , T4_Callback_3, td); } else { int result = pCON->execute( Commit ); T4_Callback_3(result, pCON, (void*)td); return; }//if } else { if (stat_async == 1) { pCON->executeAsynchPrepare( Rollback , T4_Callback_3, td); } else { int result = pCON->execute( Rollback ); T4_Callback_3(result, pCON, (void*)td); return; }//if } }
void T3_Callback_2(int result, NdbConnection * pCON, void * threadData) { ThreadData * td = (ThreadData *)threadData; if (result == -1) { CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); td->pNDB->closeTransaction(pCON); start_T3(td->pNDB, td, stat_async); return; }//if Uint32 permission = td->transactionData.permission; Uint32 sessions = td->transactionData.sessions; Uint32 server_bit = td->transactionData.server_bit; if(((permission & server_bit) == server_bit) && ((sessions & server_bit) == server_bit)) { memcpy(td->transactionData.suffix, &td->transactionData.number[SFX_START], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id, SUBSCRIBER_NUMBER_SUFFIX_LENGTH, td->transactionData.suffix); /* Operations 3 + 4 */ if (td->ndbRecordSharedData) { /* Op 3 */ char* rowPtr= (char*) &td->transactionData; const NdbRecord* record= td->ndbRecordSharedData-> sessionTableNdbRecord; Uint32 m=0; unsigned char* mask= (unsigned char*) &m; SET_MASK(mask, IND_SESSION_DATA); const NdbOperation* MyOp = pCON->readTuple(record, rowPtr, record, rowPtr, NdbOperation::LM_SimpleRead, mask); CHECK_NULL((void*) MyOp, "T3-3: readTuple", td, pCON->getNdbError()); /* Op 4 */ record= td->ndbRecordSharedData-> serverTableNdbRecord; m= 0; /* Attach interpreted program */ NdbOperation::OperationOptions opts; opts.optionsPresent= NdbOperation::OperationOptions::OO_INTERPRETED; opts.interpretedCode= td->ndbRecordSharedData->incrServerReadsProg; MyOp= pCON->updateTuple(record, rowPtr, record, rowPtr, mask, &opts, sizeof(opts)); CHECK_NULL((void*) MyOp, "T3-3: updateTuple", td, pCON->getNdbError()); } else { NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); CHECK_NULL(MyOp, "T3-3: getNdbOperation", td, pCON->getNdbError()); MyOp->simpleRead(); MyOp->equal(IND_SESSION_SUBSCRIBER, (char*)td->transactionData.number); MyOp->equal(IND_SESSION_SERVER, (char*)&td->transactionData.server_id); MyOp->getValue(IND_SESSION_DATA, (char *)td->transactionData.session_details); MyOp = pCON->getNdbOperation(SERVER_TABLE); CHECK_NULL(MyOp, "T3-4: getNdbOperation", td, pCON->getNdbError()); MyOp->interpretedUpdateTuple(); MyOp->equal(IND_SERVER_ID, (char*)&td->transactionData.server_id); MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, (char*)td->transactionData.suffix); MyOp->incValue(IND_SERVER_READS, (uint32)1); } td->transactionData.branchExecuted = 1; } else { DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", SUBSCRIBER_NUMBER_LENGTH, td->transactionData.number, td->transactionData.server_id); td->transactionData.branchExecuted = 0; } if (stat_async == 1) { pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); } else { int result = pCON->execute( Commit ); T3_Callback_3(result, pCON, (void*)td); return; }//if }
int set_thread_affinity(int cpuid) { unsigned long mask = 0xffffffff; unsigned int len = sizeof(mask); #ifdef _WIN32 HANDLE hThread; #endif #ifdef _WIN32 SET_MASK(cpuid) hThread = GetCurrentThread(); if (SetThreadAffinityMask(hThread, mask) == 0) { return -1; } #elif CMK_HAS_PTHREAD_SETAFFINITY #ifdef CPU_ALLOC if ( cpuid >= CPU_SETSIZE ) { cpu_set_t *cpusetp; pthread_t thread; size_t size; int num_cpus; num_cpus = cpuid + 1; cpusetp = CPU_ALLOC(num_cpus); if (cpusetp == NULL) { perror("set_thread_affinity CPU_ALLOC"); return -1; } size = CPU_ALLOC_SIZE(num_cpus); thread = pthread_self(); CPU_ZERO_S(size, cpusetp); CPU_SET_S(cpuid, size, cpusetp); if (errno = pthread_setaffinity_np(thread, size, cpusetp)) { perror("pthread_setaffinity dynamically allocated"); CPU_FREE(cpusetp); return -1; } CPU_FREE(cpusetp); } else #endif { int s, j; cpu_set_t cpuset; pthread_t thread; thread = pthread_self(); CPU_ZERO(&cpuset); CPU_SET(cpuid, &cpuset); if (errno = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset)) { perror("pthread_setaffinity"); return -1; } } #elif CMK_HAS_BINDPROCESSOR if (bindprocessor(BINDTHREAD, thread_self(), cpuid) != 0) return -1; #else return set_cpu_affinity(cpuid); #endif return 0; }