Skip to content

Software architecture design

CYRIL INGENIERIE edited this page Sep 10, 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)
  1. 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 the server thread associated room bit is set
    ---> if yes then selects an alternated flip-flop data memory.
    Cpu->Toggle =! Cpu->Toggle
    then clear the room bit.
    BITCLR(Proc->Room, cpu)
    ---> if no, so 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.
  1. 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);
  • for each CPU alternate flip-flop data structure, sums the ratios.
  • sets all room bits to one.
  • computes the average ratios.
  • synchronize with the client processes.
    BITSET(Shm->Proc.Sync, 0)
  • loops back to the waiting point.
  1. 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 per CPU ratios and Processor average ratios
  • loops back to the waiting point.
Clone this wiki locally