int halide_do_par_for(void *user_context, halide_task_t task, int min, int size, uint8_t *closure) { // Get the work queue mutex. We need to do a handful of hexagon-specific things. qurt_mutex_t *mutex = (qurt_mutex_t *)(&work_queue.mutex); if (!work_queue.initialized) { // The thread pool asssumes that a zero-initialized mutex can // be locked. Not true on hexagon, and there doesn't seem to // be an init_once mechanism either. In this shim binary, it's // safe to assume that the first call to halide_do_par_for is // done by the main thread, so there's no race condition on // initializing this mutex. qurt_mutex_init(mutex); } wrapped_closure c = {closure, qurt_hvx_get_mode()}; // Set the desired number of threads based on the current HVX // mode. int old_num_threads = halide_set_num_threads((c.hvx_mode == QURT_HVX_MODE_128B) ? 2 : 4); // We're about to acquire the thread-pool lock, so we must drop // the hvx context lock, even though we'll likely reacquire it // immediately to do some work on this thread. qurt_hvx_unlock(); int ret = Halide::Runtime::Internal::default_do_par_for(user_context, task, min, size, (uint8_t *)&c); qurt_hvx_lock((qurt_hvx_mode_t)c.hvx_mode); // Set the desired number of threads back to what it was, in case // we're a 128 job and we were sharing the machine with a 64 job. halide_set_num_threads(old_num_threads); return ret; }
/*========================================================================== FUNCTION uGPIOInt_Init DESCRIPTION See uGPIOIntUser.h ==========================================================================*/ int32 uGPIOInt_Init(void) { uint32 index; uint32 BaseOffset; int32 nResult; BaseOffset = 0x11; if(uGPIOIntData.uGPIOInt_Init != 1) { /* * We get the mapping of all supported direct connect interrupts from DALGPIOInt. . * This is done at power up. . */ qurt_mutex_init(&uGPIOIntData.uGPIOIntLock); uGPIOIntData.puGPIOIntConfigMap = &uGPIOIntConfigMap; index = 0; uGPIOIntData.direct_intr_number = 0; while (uGPIOIntData.puGPIOIntConfigMap[index].qurt_interrupt_id !=0) { uGPIOIntData.direct_intr_number ++; index ++; } if (uGPIOIntData.direct_intr_number < MAX_NUMBER_OF_UGPIOS) { /* * The number of supported UGPIO Interrupts should never exceed * the number of Direct Connect GPIO interrupts available. */ return UGPIOINT_ERROR; } /* * Initialize the uGPIO state table. * The interrupt configuration is fixed for the 10 configurations possible in hw for 10 direct connects. */ for(index =0;index < uGPIOIntData.direct_intr_number; index++) { uGPIOIntData.state[index].qurt_intr_id = uGPIOIntData.puGPIOIntConfigMap[index].qurt_interrupt_id; uGPIOIntData.state[index].nInterruptMask = (1<< index); uGPIOIntData.nGPIOIntMask |= uGPIOIntData.state[index].nInterruptMask; uGPIOIntData.state[index].nGPIO = UGPIOINT_NONE; uGPIOIntData.state[index].nIntRegMask = 1<< (index + BaseOffset); } /* * Initialize the uGPIO LUT table. this the full size of 200 GPIOs */ for(index =0;index < MAX_NUMBER_OF_GPIOS; index++) { uGPIOIntData.aGPIOLUT[index] = UGPIOINT_NONE; } uGPIOIntData.nThreadID = 0; uGPIOIntData.nGPIOIntRegistrationMask = UGPIOINT_TASK_INTMASK; /* * Spawn the IST here in init so it can wait for registration commands when the client registers. */ nResult = uGPIOInt_ConfigureIST(); uGPIOIntData.ugpioint_qdi = qurt_qdi_open(uGPIOIntQdiName); if (uGPIOIntData.ugpioint_qdi < 0) { nResult = UGPIOINT_ERROR; } if (nResult == UGPIOINT_SUCCESS) { uGPIOIntData.uGPIOInt_Init = 1; } return nResult; } return UGPIOINT_SUCCESS; } /* END uGPIOInt_Init */