-
Notifications
You must be signed in to change notification settings - Fork 130
Software architecture design
- One Producer instance per CPU
- One Consumer instance per CPU
- One server daemon process
- Many client processes
-
Producer
One kernel thread bound to a CPU id.
Cycle_<ArchName>()
functions defined in intelfreq.c -
Consumer
One user-space thread bound to the same CPU id.
Core_Cycle()
function defined in intelfreq.c -
Time division
A single timer which periodically notifies the kernel threads to start execution.
Cycle_Timer()
function defined in intelfreq.c -
Priority
1- kernel thread executes first,
2- user-space thread executes next.
-
Producer
One private data allocated memory per kernel thread.
KPRIVATE{}
structure defined in intelfreq.hOne public data allocated memory per kernel thread, shared between the kernel thread and the server thread.
KPUBLIC{}
structure defined in intelfreq.hA global data allocated memory shared between the kernel process and the server process.
PROC{}
structure defined in intelapi.h -
Consumer
One public data allocated memory per server thread shared with the client processes.
CPU_STRUCT{}
structure defined in corefreq.hA global data allocated memory shared between the server and the client processes.
PROC_STRUCT{}
structure defined in corefreq.h -
Server & Clients
A data memory space of shared pointers between the server and the client processes.
SHM_STRUCT{}
structure defined in corefreq.h
1- Kernel thread waits for a completion synchronization in Cycle_<ArchName>()
functions.
Cycle_<ArchName>() {
wait_for_completion_timeout(&KPrivate->Join[cpu]->Elapsed)
}
2- Timer wakes all kernel threads up through their private completion variable
hrtimer_restart() {
/* for all CPU */
complete(&KPrivate->Join[cpu]->Elapsed)
/* then rearm the timer for a future interruption */
hrtimer_forward()
}
3- Each kernel thread:
- reads some Core data, such as:
counters state.Counters_<ArchName>()
temperatureCore_Thermal()
- updates the public kernel data structure.
CORE{}
structure defined in intelapi.h - synchronizes with the user-space thread.
BITSET(Core->Sync.V, 0)
4- Each server thread:
- waits to start execution in
Core_Cycle()
- sleeps and periodically watches for a kernel synchronization change.
usleep(Proc->msleep * 100)```
* resets the kernel synchronization variable.
`BITCLR(Core->Sync.V, 0)`
* checks if its associated room bit is raised
---> if true then selects an alternated flip-flop data memory.
`Cpu->Toggle =! Cpu->Toggle`
and clear the room bit.
`BITCLR(Proc->Room, cpu)`
---> if false, keeps the current flip-flop data memory.
* computes some CPU ratios from the public kernel thread data structure.
`CORE{}`
* fills the selected flip-flop data structure with the computed ratios.
`FLIP_FLOP{}` sub-structure of `CPU_STRUCT{}` defined in [corefreq.h](https://github.com/cyring/CoreFreq/blob/master/corefreq.h)
* loops back to the waiting point.
5- Aggregation Server thread:
* waits to start execution in `Proc_Cycle()`
* sleeps until all room bits are cleared.
` while(BITWISEAND(Shm->Proc.Room,roomSeed))`
` usleep(Shm->Proc.msleep * 100);`
* sums the ratios from each CPU alternate flip-flop data structure.
* sets all room bits to one.
* computes the average ratios.
* synchronizes with the client processes.
`BITSET(Shm->Proc.Sync, 0)`
* loops back to the waiting point.
6- Client process:
* waits to start execution in [corefreq-cli.c](https://github.com/cyring/CoreFreq/blob/master/corefreq-cli.c)
* sleeps and periodically watches for a server synchronization change.
` while(!BITWISEAND(Shm->Proc.Sync, 0x1) && !Shutdown)`
` usleep(Shm->Proc.msleep * 100);`
` BITCLR(Shm->Proc.Sync, 0);`
* displays CPU ratios and Processor average ratios
* loops back to the waiting point.
CoreFreq |
---|
2.0.0 |