~hecanjog/pippi

4e7140794f0bcd470f3db852c5f728910cd8f0d1 — Erik Schoster a year ago 05bbc2b
Move counter handling logic into astrid library
M astrid/src/astrid.c => astrid/src/astrid.c +89 -0
@@ 12,6 12,95 @@ void lptimeit_since(struct timespec * start) {
    start->tv_nsec = now.tv_nsec;
}

int lpcounter_read_and_increment(lpcounter_t * c) {
    struct sembuf sop;
    size_t * counter;
    int counter_value;

    /* Aquire lock */
    sop.sem_num = 0;
    sop.sem_op = -1;
    sop.sem_flg = 0;
    if(semop(c->semid, &sop, 1) < 0) {
        perror("semop");
        return -1;
    }

    /* Read the current value */
    counter = shmat(c->shmid, NULL, 0);
    counter_value = *counter;

    /* Increment the counter */
    *counter += 1;

    /* Release lock */
    sop.sem_num = 0;
    sop.sem_op = 1;
    sop.sem_flg = 0;
    if(semop(c->semid, &sop, 1) < 0) {
        perror("semop");
        return -1;
    }

    return counter_value;
}

int lpcounter_destroy(lpcounter_t * c) {
    union semun dummy;

    /* Remove the semaphore and shared memory counter */
    if(shmctl(c->shmid, IPC_RMID, NULL) < 0) {
        perror("shmctl");
        return -1;
    }

    if(semctl(c->semid, 0, IPC_RMID, dummy) < 0) {
        perror("semctl");
        return -1;
    }

    /* Don't need to free the struct since it's just two 
     * ints on the stack... */
    return 0;
}

int lpcounter_create(lpcounter_t * c) {
    size_t * counter;
    union semun arg;

    /* Create the shared memory space for the counter value */
    c->shmid = shmget(IPC_PRIVATE, sizeof(size_t), IPC_CREAT | 0600);
    if (c->shmid < 0) {
        perror("shmget");
        return -1;
    }

    /* Create the semaphore used as a read/write lock on the counter */
    c->semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
    if (c->semid < 0) {
        perror("semget");
        return -1;
    }

    /* Attach the shared memory for reading and writing */
    counter = shmat(c->shmid, NULL, 0);
    if (counter == (void*)-1) {
        perror("shmat");
        return -1;
    }

    /* Start the voice IDs at 1 */
    *counter = 1;

    /* Prime the lock by initalizing the sempahore to 1 */
    arg.val = 1;
    if(semctl(c->semid, 0, SETVAL, arg) < 0) {
        perror("semctl");
        return -1;
    }

    return 0;
}

int lpadc_create() {
    int shmid, count;

M astrid/src/astrid.h => astrid/src/astrid.h +8 -0
@@ 50,6 50,11 @@ union semun {
#endif
};

typedef struct lpcounter_t {
    int shmid;
    int semid;
} lpcounter_t;

typedef struct lpmsg_t {
    size_t delay;
    size_t voice_id;


@@ 92,6 97,9 @@ lpscheduler_t * scheduler_create(int, int, lpfloat_t);
void scheduler_destroy(lpscheduler_t * s);
void lpscheduler_handle_callbacks(lpscheduler_t * s);

int lpcounter_create(lpcounter_t * c);
int lpcounter_read_and_increment(lpcounter_t * c);
int lpcounter_destroy(lpcounter_t * c);

typedef struct lpdacctx_t {
    lpscheduler_t * s;

M astrid/src/getvoiceid.c => astrid/src/getvoiceid.c +8 -35
@@ 1,45 1,18 @@
#include "astrid.h"

int main(int argc, char * argv[]) {
    int semid, shmid;
    struct sembuf sop;
    size_t * counter;
    lpcounter_t c;
    int voice_id;

    openlog("astrid-getvoiceid", LOG_PID, LOG_USER);
    c.semid = atoi(argv[1]);
    c.shmid = atoi(argv[2]);

    semid = atoi(argv[1]);
    shmid = atoi(argv[2]);

    /* Aquire lock */
    sop.sem_num = 0;
    sop.sem_op = -1;
    sop.sem_flg = 0;
    printf("Aquiring lock...");
    if(semop(semid, &sop, 1) < 0) {
        perror("semop");
        goto exit_with_error;    
    if((voice_id = lpcounter_read_and_increment(&c)) < 0) {
        perror("lpcounter_create");
        return 1;
    }

    /* Read the current voice ID */
    counter = shmat(shmid, NULL, 0);
    printf("Voice ID: %d\n", (int)(*counter));

    printf("Incrementing the counter...\n");
    *counter += 1;

    /* Release lock */
    sop.sem_num = 0;
    sop.sem_op = 1;
    sop.sem_flg = 0;
    printf("Releasing the lock...\n");
    if(semop(semid, &sop, 1) < 0) {
        perror("semop");
        goto exit_with_error;    
    }
    printf("Voice ID: %d\n", voice_id);

    return 0;

exit_with_error:
    syslog(LOG_ERR, "Exited with error\n");
    return 1;
}

M astrid/src/makecounter.c => astrid/src/makecounter.c +6 -40
@@ 1,50 1,16 @@
#include "astrid.h"

int main() {
    int semid, shmid;
    size_t * counter;
    union semun arg;
    lpcounter_t c;

    openlog("astrid-makecounter", LOG_PID, LOG_USER);

    /* Create the shared memory space for the counter value */
    shmid = shmget(IPC_PRIVATE, sizeof(size_t), IPC_CREAT | 0600);
    if (shmid < 0) {
        perror("shmget");
        goto exit_with_error;    
    }

    /* Create the semaphore used as a read/write lock on the counter */
    semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
    if (semid < 0) {
        perror("semget");
        goto exit_with_error;    
    }

    /* Attach the shared memory for reading and writing */
    counter = shmat(shmid, NULL, 0);
    if (counter == (void*)-1) {
        perror("shmat");
        goto exit_with_error;    
    }

    /* Start the voice IDs at 1 */
    *counter = 1;

    /* Prime the lock by initalizing the sempahore to 1 */
    arg.val = 1;
    if(semctl(semid, 0, SETVAL, arg) < 0) {
        perror("semctl");
        goto exit_with_error;    
    if(lpcounter_create(&c) > 0) {
        perror("lpcounter_create");
        return 1;
    }

    /* Print the IDs for testing */
    printf("shmid = %d\n", shmid);
    printf("semid = %d\n", semid);
    printf("shmid = %d\n", c.shmid);
    printf("semid = %d\n", c.semid);

    return 0;

exit_with_error:
    syslog(LOG_ERR, "Exited with error\n");
    return 1;
}

M astrid/src/rmcounter.c => astrid/src/rmcounter.c +6 -19
@@ 1,28 1,15 @@
#include "astrid.h"

int main(int argc, char * argv[]) {
    int semid, shmid;
    union semun dummy;
    lpcounter_t c;

    openlog("astrid-getvoiceid", LOG_PID, LOG_USER);
    c.semid = atoi(argv[1]);
    c.shmid = atoi(argv[2]);

    semid = atoi(argv[1]);
    shmid = atoi(argv[2]);

    /* Remove the semaphore and shared memory counter */
    if(shmctl(shmid, IPC_RMID, NULL) < 0) {
        perror("shmctl");
        goto exit_with_error;
    }

    if(semctl(semid, 0, IPC_RMID, dummy) < 0) {
        perror("semctl");
        goto exit_with_error;
    if(lpcounter_destroy(&c) > 0) {
        perror("lpcounter_create");
        return 1;
    }

    return 0;

exit_with_error:
    syslog(LOG_ERR, "Exited with error\n");
    return 1;
}