在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
芯片精品文章合集(500篇!) 创芯人才网--重磅上线啦!
查看: 3160|回复: 2

[求助] 求高手帮忙:程序改错

[复制链接]
发表于 2012-4-19 04:51:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
操作系统公司面试题,要求改下面程序的错误。请教各位高手帮忙看看,到底有些什么地方需要改?
这是题目的要求:
Timers (tick tock, tick tock)
=============================

The timers.c file represents a very simple timer framework which allows you to
setup event handling based on a timeout.  The basic primitives allow the
programmer to:
    -allocate or free timers
    -arm/disarm timers
    -set attributes and timeout for a timer

Currently, the self contained example will create timers up to the maximum
(currently defined as 10) with random timeout values from up to 20 seconds.
Each timer will eventually expire and the associated call-back function executed.

The assignment is to identify as many weaknesses or bugs in the framework as you
can find.  You are welcome to identify any type of issue you feel is relevant.
Anything from logic errors to algorithmic limitations are fair game for
identification.  Each issue identified should have an illustrative text description
of the problem and a proposed fix with code.

If you have any issues building the source or running the example, please do not
hesitate to contact.


这是需要修改的程序:


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <inttypes.h>
#include <sys/queue.h>

#define NUM_TIMERS 10
#define MAX_RANDOM_TIME_MS    20000

enum timer_callback_retval {
    CB_RETURN_NORMAL = 0,
    CB_RETURN_FREE_TIMER,
    CB_RETURN_INVALID,
};

enum timer_type {
    TT_RELATIVE = 0,
    TT_ABSOLUTE,
    TT_INVALID,
};

/* Define our timer list type */
TAILQ_HEAD(timer_list, timer_node);

/* Master tick clock/count */
uint64_t tick_cnt = 0;

/*
    Timer data structure:
    -the linked list
    -the monotonic fire time (saved as an absolute time)
    -the user callback handler to run on expiry of timer
    -the registered data pointer to pass to the user callback
*/
struct timer_node {
    TAILQ_ENTRY(timer_node) entries;
    uint64_t fire;
    int (*cb)(void* user_data);
    void *user_data;
};

/* Our global timer lists */
struct timer_list active_timers;
struct timer_list free_timers;
struct timer_node *timer_memory;

#ifdef DEBUG
/* print out the contents of a given timer list */
void print_list(struct timer_list *list) {
    struct timer_node *np;
    TAILQ_FOREACH(np, list, entries) {
        printf("timer fire %llu\n", np->fire);
    }
}
#endif

/* put a timer onto the free list */
static void free_timer(struct timer_node *timer) {
    TAILQ_INSERT_HEAD(&free_timers, timer, entries);
}

/* pull an available timer off the free list */
static struct timer_node* alloc_timer(void) {
    struct timer_node *np;
    if(TAILQ_EMPTY(&free_timers)) return NULL;

    np=TAILQ_FIRST(&free_timers);
    TAILQ_REMOVE(&free_timers, np, entries);
    return np;
}

/* put a timer onto the actives timer queue */
static void arm_timer(struct timer_node* timer) {
    struct timer_node *np;

    if(TAILQ_EMPTY(&active_timers)) {
        TAILQ_INSERT_HEAD(&active_timers, timer, entries);
    } else {
        for(np=TAILQ_FIRST(&active_timers) ; np ; np=TAILQ_NEXT(np, entries)) {
            if(timer->fire < np->fire) {
                TAILQ_INSERT_BEFORE(np, timer, entries);
                return;
            }
        }
        TAILQ_INSERT_TAIL(&active_timers, timer, entries);
    }
}

/* remove a timer from the actives timer queue */
static void disarm_timer(struct timer_node* timer) {
    TAILQ_REMOVE(&active_timers, timer, entries);
    return;
}

/*    set timer attributes such as relative/absolute fire timer,
    fire timer, callback and user data passed to callback
*/
static int set_timer(struct timer_node* timer, enum timer_type tt, uint64_t fire, int (*cb)(void*), void* user_data) {
    switch(tt) {
        case TT_RELATIVE:
            fire+=tick_cnt;
            break;
        case TT_ABSOLUTE:
            break; /* do nothing */
        case TT_INVALID:
        default:
            return -1;
    }
    timer->fire = fire;
    timer->cb = cb;
    timer->user_data = user_data;
    return 0;
}


/* initialisation of the timer subsystem */
static void init_timers(void) {
    unsigned i;

    TAILQ_INIT(&active_timers);
    TAILQ_INIT(&free_timers);

    /*    We're preallocating the memory and using a fixed timer pool size to keep
        things simpler and avoid cluttering this exercise with lots of error checking
        for bad memory conditions.  This works or we're toast.
    */
    if((timer_memory = malloc(sizeof(struct timer_node)*NUM_TIMERS)) == NULL) {
        perror("Fatal! Can't allocate our block of timers!");
        exit(EXIT_FAILURE);
    }

    /* seed our free timer list */   
    for(i=0 ; i < NUM_TIMERS; i++) {
        free_timer(&timer_memory[i]);
    }
}

/* Our clock handling routine that runs each clock tick */
static void clock_tick(int signo) {
    struct timer_node *np;
   
    tick_cnt++;   
    while(!TAILQ_EMPTY(&active_timers) && (np=TAILQ_FIRST(&active_timers)) && np->fire <= tick_cnt) {
        disarm_timer(np);
        if(np->cb(np->user_data) == CB_RETURN_FREE_TIMER) free_timer(np);
    }

}

/*    Setup a simulated clock tick that functions much like a real clock
    interrupt might.  We're using *NIX signals and a process timer as
    it is a very common service available on almost any *NIX like system.
    While not perfect, it's good enough to be illustrative.
*/
static int init_ticker(unsigned ms) {
    struct itimerval it;
    struct timeval tv;

    tv.tv_sec = 0;
    tv.tv_usec = ms*1000;

    it.it_interval = it.it_value = tv;
    signal(SIGALRM, clock_tick);
    return setitimer(ITIMER_REAL, &it, NULL);
}

/* The user timer callback function */
int tcb(void *data) {
    struct timer_node *np = data;

    /*    Normally you wouldn't only printf() as a result of a timer
        but it is sufficient to be illustrative.
    */   
    printf("Timer Callback : %llu\n", np->fire);
    return CB_RETURN_FREE_TIMER;
}

int main(int argc, char* argv[]) {
    struct timer_node *np;
    int i;

    init_timers(); /* init the timer subsystem */
    init_ticker(1); /* 1ms tick simulating a hw clock */

    /* Create a bunch of timers from 1 to 5000ms in time and arm them */
    for (i=0 ; i < NUM_TIMERS ; i++) {
        if((np = alloc_timer()) == NULL) {
            perror("Fatal! we ran out of timers?");
            exit(EXIT_FAILURE);
        }

        if(set_timer(np, 0, (rand()+1) % MAX_RANDOM_TIME_MS , tcb, np) == -1) {
            perror("Fatal! Bad timer set!");
            exit(EXIT_FAILURE);
        }
        arm_timer(np);
    }

    /* Sit around letting the timers expire - not pretty but simple */
    while(1) {
        sleep(100);
    }

    /* never reached */

    return 0;
}
发表于 2012-5-10 14:22:19 | 显示全部楼层
难在编译
发表于 2012-7-2 18:41:17 | 显示全部楼层
这个比较费脑子啊,看别人的程序比较麻烦
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-23 18:20 , Processed in 0.051941 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表