Another possibility, simulating the timers.
Code:
#include <stdio.h>
 
typedef struct Worker {
    void (*fn)(void);
    const char *name;
    int counter;
} Worker;
 
typedef struct Controller {
    int overflow;
    int n; // next worker to call
    Worker workers[3];
} Controller;
 
typedef struct Timer {
    int count;
    int max;
    int overflow_flag;
} Timer;
 
Timer timers[3] = {
    { 0,  50, 0 },
    { 0, 100, 0 },
    { 0, 150, 0 }
};
 
enum { CPUTIMER0_BASE, CPUTIMER1_BASE, CPUTIMER2_BASE };
 
int overall_timer = 0;
 
void update_timers() {
    overall_timer += 10;
    for (int i = 0; i < 3; ++i)
        if ((timers[i].count += 10) >= timers[i].max)
            timers[i].overflow_flag = 1;
}
 
int CPUTimer_getTimerOverflowStatus(int cputimer) {
    return timers[cputimer].overflow_flag;
}
 
void CPUTimer_clearOverflowFlag(int cputimer) {
    timers[cputimer].overflow_flag = 0;
    timers[cputimer].count = 0;
}
 
void A1(void) { }
void A2(void) { }
void A3(void) { }
void B1(void) { }
void B2(void) { }
void B3(void) { }
void C1(void) { }
void C2(void) { }
void C3(void) { }
 
Controller controllers[3] = {
    {
        CPUTIMER0_BASE,
        0,
        {
            { A1, "A1", 0 },
            { A2, "A2", 0 },
            { A3, "A3", 0 }
        },
    },
    {
        CPUTIMER1_BASE,
        0,
        {
            { B1, "B1", 0 },
            { B2, "B2", 0 },
            { B3, "B3", 0 }
        },
    },
    {
        CPUTIMER2_BASE,
        0,
        {
            { C1, "C1", 0 },
            { C2, "C2", 0 },
            { C3, "C3", 0 }
        },
    }
};
 
int main() {
    for (int t = 0; t < 100; ++t) {
        update_timers();
        for (int i = 0; i < 3; ++i) {
            Controller *c = &controllers[i];
            if (CPUTimer_getTimerOverflowStatus(c->overflow))
            {
                CPUTimer_clearOverflowFlag(c->overflow);
 
                Worker *w = &c->workers[c->n];
                w->fn();
                ++w->counter;
 
                printf("%4d %s %3d\n", overall_timer, w->name, w->counter);
 
                c->n = (c->n + 1) % 3;
            }
        }
    }
 
    printf("\nCounts:\n"); 
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 3; ++j) {
            Worker *w = &controllers[i].workers[j];
            printf("%s %4d\n", w->name, w->counter);
        }
    }
 
    return 0;
}

  50 A1   1
 100 A2   1
 100 B1   1
 150 A3   1
 150 C1   1
 200 A1   2
 200 B2   1
 250 A2   2
 300 A3   2
 300 B3   1
 300 C2   1
 350 A1   3
 400 A2   3
 400 B1   2
 450 A3   3
 450 C3   1
 500 A1   4
 500 B2   2
 550 A2   4
 600 A3   4
 600 B3   2
 600 C1   2
 650 A1   5
 700 A2   5
 700 B1   3
 750 A3   5
 750 C2   2
 800 A1   6
 800 B2   3
 850 A2   6
 900 A3   6
 900 B3   3
 900 C3   2
 950 A1   7
1000 A2   7
1000 B1   4

Counts:
A1    7
A2    7
A3    6
B1    4
B2    3
B3    3
C1    2
C2    2
C3    2