Skip to content

Software architecture design

CYRIL INGENIERIE edited this page Sep 13, 2015 · 23 revisions

Architecture

Producer / Consumer

  • One Producer instance per CPU
  • One Consumer instance per CPU

Client / Server

  • One server daemon process
  • Many client processes

Instructions

  • 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.

Data

  • Producer
    One private data allocated memory per kernel thread.
    KPRIVATE{} structure defined in intelfreq.h

    One public data allocated memory per kernel thread, shared between the kernel thread and the server thread.
    KPUBLIC{} structure defined in intelfreq.h

    A 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.h

    A 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

Algorithm:

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>()
    temperature Core_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.  
Clone this wiki locally