///////////////////////////////////////////for client
        //start main loop
        public void mainflow()
        {
            if (shutdownval)
            {
                Environment.Exit(0);
            }

            settings.checkTimeSync();   //update changed time settings

            //internal sync
            if (settings.timeSync && !controller.wrong && !pause) //skip when xtu settings bad, or user request
            {
                controller.XTUdaemon(settings, checker);

                //1. check config
                controller.generateCLKlist(settings, checker); //before batchCheck
                settings.batchCheckFiles();                    //no need to save io here
                if (settings.checkPowerCFGFlag)
                {
                    controller.initPowerCFG(settings);
                    controller.forceApply = true;   //just in case
                }

                //2. apply settings(add app if dont exist)
                var currfg = checker.detectFgProc(settings);
                checker.autoCheckInsert(currfg, settings, controller);
                //controller.setProcNice(currfg, settings);
                controller.setPower(currfg, settings);

                //3. check throttle

                /*
                 *
                 *  per profile scheduling.
                 *
                 *  store intermediate values on settingsmanager.
                 *
                 *  on throttle:
                 *      cpuload 80%(tweakable)
                 *      -get median upto throttleSync(tweakable)
                 *
                 *  if app on the same profile throttles:
                 *      profile gets modified affecting other relevant apps.
                 *
                 *  if app is not in any profile:
                 *      monitor performance for throttleSync(tweakable) cycles and assign to closest one.
                 *
                 */


                /*current app info
                 *  1. skip if its not in list
                 *  2. which throttle mode
                 */

                //reset timers (except newlist does it internally)
                if (prev_currfg != null)
                {
                    if (currfg.Id != prev_currfg.Id)
                    {
                        settings.resetThrottleSync();
                        settings.resetResurSync();
                    }
                }
                prev_currfg = currfg;

                //current profile:
                int currprof = controller.checkInList(currfg, settings);

                //if app has a profile:
                if (currprof != -1)
                {
                    if (checker.isCurrentlyThrottling(settings, controller))
                    {
                        int mode = settings.throttleMode; //save mode
                        settings.throttleMode = 0;        //reset

                        //median limit
                        int limit      = (int)settings.newlist_median.configList["newlist_median"]; //ex) 50
                        int listcount  = settings.generatedCLK.configList.Count();                  //ex) 12
                        int indexlimit = listcount - listcount * limit / 100;                       //ex) 6

                        //new clk value for cpu throttle (newclk)
                        var gclklist = checker.sortedCLKlist(settings);
                        int newindex = gclklist.IndexOf(controller.getCLK(false));
                        if (newindex > indexlimit)
                        {
                            newindex--;                            //ensure 0 is the end(noindex is -1)
                        }
                        int newclk = gclklist.ElementAt(newindex); //clk value goes in

                        //new xtu value for gpu throttle (newxtu)
                        float newxtu = controller.getXTU();
                        if (newxtu > controller.getBaseXTU(settings))
                        {
                            newxtu -= 0.5f;
                        }

                        switch (mode)
                        {
                        case 0: break;

                        case 1:     //cpu
                            settings.programs_running_cfg_cpu.appendChanges(currprof, newclk);

                            break;

                        case 2:     //gpu
                            settings.programs_running_cfg_xtu.appendChanges(currprof, newxtu);


                            break;
                        }
                    }
                    if (checker.isViableForResurrect(settings, controller))
                    {
                        int mode = settings.resurrectMode;
                        settings.resurrectMode = 0;

                        //median limit
                        int limit      = (int)settings.newlist_median.configList["newlist_median"]; //ex) 50
                        int listcount  = settings.generatedCLK.configList.Count();                  //ex) 12
                        int indexlimit = listcount - listcount * limit / 100;                       //ex) 6

                        string name = controller.checkNameInList(currfg, settings);
                        switch (mode)
                        {
                        case 0: break;

                        case 1:
                            if (currprof > 0)
                            {
                                settings.special_programs.appendChanges(name, currprof - 1);
                            }
                            break;

                        case 2:
                            if (currprof < indexlimit)
                            {
                                settings.special_programs.appendChanges(name, currprof + 1);
                            }
                            break;
                        }
                    }
                }
            }
            settings.updateTimeSync();
            checker.resettick();
        }
        /* its currently throttling if:
         * 1. get default high watermark from:
         *              06cadf0e-64ed-448a-8927-ce7bf90eb35d = 30   //rocket
         * 2. if load is over 30 and clockspeed is not fullspeed -> throttling.
         */
        /*
         * sm.throttleMode:
         * 0 -> nein
         * 1 -> cpu(cpu usage under 80)
         * 2 -> gpu(cpu usage over 80)
         * cpu is more important than gpu
         */
        public bool isCurrentlyThrottling(SettingsManager sm, TweakerController ts)
        {
            sm.IPClocked = true;

            try
            {
                /*
                 * ex) 1 sync = 5 cycles
                 *
                 *  all cycles synchronized under:
                 *      -throttleSync
                 *
                 *  throttle decision is done by:
                 *      -throttledelay(2/5 no throttle: nothing happens in this sync)
                 *
                 *  which side to throttle is decided by:
                 *      -throttle_acc median(accumulates all throttled cycle over throttledelay)
                 *      -user tweakable throttle_median bar
                 */

                //<string, int>
                int currpwr         = autofilterPWR(getPWR());
                int load            = getLoad();
                int currclk         = ts.getCLK(false);
                int target_pwr      = autofilterPWR((int)sm.generatedCLK.configList[currclk]);
                int throttle_median = (int)sm.throttle_median.configList["throttle_median"];
                int upperlimit      = (int)sm.processor_guid_tweak.configList["06cadf0e-64ed-448a-8927-ce7bf90eb35d"];

                if (throttlecheck == 0)
                {
                    throttle_acc.Clear();
                }

                if (load >= upperlimit && currpwr < target_pwr)
                {
                    sm.startThrottleSync();
                    throttle_acc.Add(load);
                    throttlecheck++;
                }
                else
                {
                    if (throttlecheck > 0)
                    {
                        throttlecheck--;
                    }
                }

                log.WriteLog("accumulation for throttle load = " + load + " ,clk = " + currpwr + " ,throttlecheck = " + throttlecheck);


                /*
                 *  on throttle:
                 *      cpuload 80%(tweakable)
                 *      -get average upto throttleSync(tweakable)
                 */

                //on throttleSync timer
                if (sm.checkThrottleSync())
                {
                    sm.throttleMode = 0;

                    /*
                     * get avg.
                     * heavily modified version of exponential moving average(EMA)
                     * EMA is highest, EMA + CMA helps in some scenarios
                     * designed to be more favorable towards higher load for avg
                     */
                    float favg       = throttle_acc[0];
                    float lsum       = 0.0f;
                    bool  ignoreFlag = false;
                    for (int i = 1; i < throttle_acc.Count(); i++)
                    {
                        //ignore
                        if (throttle_acc[i] == 100 && ignoreFlag == false)
                        {
                            ignoreFlag = true;
                            favg       = 100.0f;
                            //skip the next one
                        }
                        else if (throttle_acc[i] == 100 && ignoreFlag == true)
                        {
                            continue;   //skip
                        }
                        else if (throttle_acc[i] != 100 && ignoreFlag == true)
                        {
                            ignoreFlag = false;
                        }

                        //favg
                        float next = throttle_acc[i];
                        lsum = next + favg + 1.0f;   //prevent divbyzero
                        favg = favg * (1.0f - next / lsum) + next * (next / lsum);
                    }
                    int avg = (int)favg;    //int version


                    int medload = avg;
                    log.WriteLog("EMA result medload:" + medload);

                    //this is count instead of value
                    int countval = 100 * throttlecheck / (throttle_acc.Count() + 1); //prevent divbyzero
                    log.WriteLog("count percentage:" + countval);
                    throttle_acc.Clear();                                            //clear
                    throttlecheck = 0;                                               //reset acc
                    if (countval < throttle_median)
                    {
                        log.WriteLog("throttle check ignored.");
                        return(false);
                    }


                    //throttleMode notifier:
                    //
                    //      dont confuse!
                    //      *throttle_median: cpu load median
                    //      *newlist_median: low limit clk median.
                    //
                    //  if throttle_acc median doesnt exceed default median (ex)80:
                    //      decrease cpu
                    //  else if cpu cant be decreased:
                    //      decrease gpu

                    log.WriteLog("complete throttle sync load(median) = " + medload);

                    //find index of low limit(newlist median)
                    int index      = 0;
                    int limit      = (int)sm.newlist_median.configList["newlist_median"]; //ex) 50
                    int listcount  = sm.generatedCLK.configList.Count();                  //ex) 12
                    int indexlimit = listcount * limit / 100;                             //ex) 6
                    //get low limit through sorted clk
                    foreach (int val in sortedCLKlist(sm))
                    {
                        if (index < indexlimit)
                        {
                            index++;
                        }
                        else
                        {
                            limit = val;
                            break;
                        }
                    }

                    //dont exceed throttle median && current clk is over limit
                    int limitclk = (int)sm.programs_running_cfg_cpu.configList[indexlimit];
                    if (medload < throttle_median && limitclk < currclk)
                    {
                        log.WriteLog("cpu throttle detected!");
                        sm.throttleMode = 1;
                    }
                    else
                    {
                        log.WriteLog("gpu throttle detected!");
                        sm.throttleMode = 2;
                        if (limitclk >= currclk)
                        {
                            log.WriteLog("reason: cpu low limit reached (newlist_median)");
                        }
                    }

                    sm.IPClocked = false;
                    //initiate throttle!
                    return(true);
                }

                sm.IPClocked = false;
                //skip for now
                return(false);
            }
            catch (Exception) { //config file bug
                //log.WriteErr("config file is broken");
            }

            sm.IPClocked = false;
            return(false);   //this will never reach
        }