Skip to content

Software architecture design

CYRIL INGENIERIE edited this page Sep 22, 2019 · 23 revisions

Outdated specification


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.
	while(!BITWISEAND(Core->Sync.V, 0x1))  
		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

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