I'm doing my assignment about thread. I need to do 3 thread, first compute temperature value, second compute pressure value and third thread, I need to pass those value and display it. But when I'm compile, I got segmentation fault (core dumped). I need to pass the argument but doesn't know where I did wrong. Can someone help me?
This is my code
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
struct param_t_p{
int temperature;
int LOWER_TEMP_BOUND,UPPER_TEMP_BOUND;
float pressure;
float LOWER_PRESURE_BOUND,UPPER_PRESURE_BOUND;
};
void timespec_add_us (struct timespec *t, long us)
{
t->tv_nsec += us*1000;
while (t->tv_nsec > 1000000000)
{
t->tv_nsec = t->tv_nsec - 1000000000;// + ms*1000000;
t->tv_sec += 1;
}
}
void *temp (void* args)
{
struct param_t_p *ps = (struct param_t_p *)args;
struct timespec time;
clock_gettime (CLOCK_REALTIME, &time);
while (1)
{
timespec_add_us(&time, 4000000);
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME,&time, NULL);
ps->temperature = ps->LOWER_TEMP_BOUND + (int)(ps->UPPER_TEMP_BOUND*rand()/(RAND_MAX+1.0));
printf("First thread for temperature is done\n\n");
}
return NULL;
}
void *press (void* args)
{
struct param_t_p *ps = (struct param_t_p *)args;
struct timespec time;
clock_gettime (CLOCK_REALTIME, &time);
while (1)
{
timespec_add_us(&time, 4000000);
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME,&time, NULL);
ps->pressure = ps->LOWER_PRESURE_BOUND +( int)(ps->UPPER_PRESURE_BOUND*rand()/(RAND_MAX+1.0));
printf("Second thread for temperature is done\n\n");
}
return NULL;
}
void *display (void* args)
{
struct param_t_p *ps = (struct param_t_p *)args;
struct timespec time;
clock_gettime (CLOCK_REALTIME, &time);
while (1)
{
timespec_add_us(&time, 4000000);
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME,&time, NULL);
printf("Value for Temperature and Pressure\n");
printf(" Temperature : %d°C\n", ps->temperature);
printf(" Pressure : %.2fPa\n", ps->pressure);
printf("Third thread is done\n\n");
}
return NULL;
}
int main()
{
pthread_t th1,th2,th3;
pthread_att_t attr;
struct sched_param param1, param2, param3;
struct param_t_p data;
data.LOWER_TEMP_BOUND=20;
data.UPPER_TEMP_BOUND=40;
data.LOWER_PRESURE_BOUND=31.5;
data.UPPER_PRESURE_BOUND=32.5;
data.temperature;
data.pressure;
printf("Process ID: %d\n\n", getpid());
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
param1.sched_priority = 1;
param2.sched_priority = 2;
param3.sched_priority = 3;
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedparam(&attr, ¶m1);
pthread_create(&th1, &attr, temp, &data);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedparam(&attr, ¶m2);
pthread_create(&th2, &attr, press, &data);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedparam(&attr, ¶m3);
pthread_create(&th3, &attr, display, &data);
pthread_attr_destroy(&attr);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
}
I need to solve it as soon as possible. Thank you in advance
Related
I needed some timer for my program, and I decided to write it with pthreads.
My timer needed to update some info via update callback every update_interval ticks.
I've done it like this:
timer.h:
#include <pthread.h>
enum timer_messages
{
TIMER_START,
TIMER_STOP,
TIMER_PAUSE,
TIMER_EXIT
};
typedef void (*callback)(void *);
struct timer
{
pthread_t thread_id;
struct timeval *interval;
struct timeval *update_interval;
struct timeval *start;
int ls;
int wr;
int enabled;
int exit;
callback update;
callback on_time;
};
struct timer *my_timer_create();
void timer_destroy(struct timer *t);
void timer_set_update_interval(struct timer *t, int seconds, int microseconds);
void timer_set_interval(struct timer *t, int seconds, int microseconds);
void timer_set_update_func(struct timer *t, callback update);
void timer_set_ontime_func(struct timer *t, callback on_time);
void timer_stop(struct timer *t);
void timer_start(struct timer *t);
void timer_exit(struct timer *t);
void timer_pause(struct timer *t);
timer.c:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include "timer.h"
#define TIMEVAL_TO_MICROSECONDS(tv) ((long long)((tv).tv_sec * 1000000 + (tv).tv_usec))
#define GET_TIME_PASSED(start, now) ((TIMEVAL_TO_MICROSECONDS(now) - TIMEVAL_TO_MICROSECONDS(start)))
static int passed(struct timeval *start, struct timeval *interval);
static void fill_timeval(struct timeval *tv, int sec, int microsec);
static void timer_count(struct timer *t);
static void timer_message(struct timer *t);
static void *main_func(void *data);
static void timer_send_msg(struct timer *t, enum timer_messages message);
static struct timeval DEFAULT_TIMEOUT = { 0, 500000 };
static int passed(struct timeval *start, struct timeval *interval)
{
struct timeval cur, sub;
int check;
check = gettimeofday(&cur, NULL);
if(-1 == check)
{
perror("gettimeofday");
return 0;
}
if(GET_TIME_PASSED(*start, cur) < TIMEVAL_TO_MICROSECONDS(*interval))
return 0;
return 1;
}
static void fill_timeval(struct timeval *tv, int sec, int microsec)
{
tv->tv_sec = sec;
tv->tv_usec = microsec;
}
static void timer_count(struct timer *t)
{
int check;
fd_set readfds;
struct timeval timeout;
check = gettimeofday(t->start, NULL);
while(1)
{
if(!t->enabled)
return;
FD_ZERO(&readfds);
FD_SET(t->ls, &readfds);
if(t->update_interval)
memcpy(&timeout, t->update_interval, sizeof(*(t->update_interval)));
else
memcpy(&timeout, &DEFAULT_TIMEOUT, sizeof(DEFAULT_TIMEOUT));
check = select(t->ls + 1, &readfds, NULL, NULL, &timeout);
if(-1 == check)
{
perror("select");
return;
}
if(FD_ISSET(t->ls, &readfds))
timer_message(t);
else
if(t->update)
t->update(t);
if(passed(t->start, t->interval))
{
t->on_time(t);
break;
}
}
}
static void timer_message(struct timer *t)
{
int read_bytes;
char message;
read_bytes = read(t->ls, &message, sizeof(message));
if(-1 == read_bytes)
{
perror("timer_message read");
return;
}
switch(message)
{
case TIMER_START: t->enabled = 1; break;
case TIMER_STOP: t->enabled = 0; t->interval = NULL; t->start = NULL; break;
case TIMER_EXIT: t->enabled = 0; t->exit = 1; break;
case TIMER_PAUSE: break;
default: break;
}
}
static void *main_func(void *data)
{
struct timer *t = data;
fd_set readfds;
int check;
while(!t->exit)
{
if(t->enabled)
{
timer_count(t);
}
else
{
FD_ZERO(&readfds);
FD_SET(t->ls, &readfds);
check = select(t->ls + 1, &readfds, NULL, NULL, NULL);
if(-1 == check)
{
perror("select");
return NULL;
}
if(FD_ISSET(t->ls, &readfds))
timer_message(t);
}
}
return NULL;
}
static void timer_send_msg(struct timer *t, enum timer_messages message)
{
int check;
char msg;
msg = message;
check = write(t->wr, &msg, sizeof(msg));
if(-1 == check)
{
perror("timer_send_msg write");
}
}
struct timer *my_timer_create()
{
int check;
struct timer *t;
int fd[2];
t = malloc(sizeof(*t));
t->interval = malloc(sizeof(*(t->interval)));
t->update_interval = malloc(sizeof(*(t->update_interval)));
t->start = malloc(sizeof(*(t->start)));
check = pipe(fd);
if(-1 == check)
{
perror("pipe");
return NULL;
}
t->ls = fd[0];
t->wr = fd[1];
t->enabled = 0;
t->exit = 0;
t->update = NULL;
t->on_time = NULL;
check = pthread_create(&(t->thread_id), NULL, main_func, t);
if(-1 == check)
{
perror("pthread_create");
return NULL;
}
return t;
}
void timer_destroy(struct timer *t)
{
free(t->interval);
free(t->update_interval);
free(t->start);
close(t->ls);
close(t->wr);
free(t);
}
void timer_set_update_interval(struct timer *t, int seconds, int microseconds)
{
fill_timeval(t->update_interval, seconds, microseconds);
}
void timer_set_interval(struct timer *t, int seconds, int microseconds)
{
fill_timeval(t->interval, seconds, microseconds);
}
void timer_set_update_func(struct timer *t, callback update)
{
t->update = update;
}
void timer_set_ontime_func(struct timer *t, callback on_time)
{
t->on_time = on_time;
}
void timer_stop(struct timer *t)
{
timer_send_msg(t, TIMER_STOP);
}
void timer_start(struct timer *t)
{
timer_send_msg(t, TIMER_START);
}
void timer_exit(struct timer *t)
{
timer_send_msg(t, TIMER_EXIT);
}
void timer_pause(struct timer *t)
{
timer_send_msg(t, TIMER_PAUSE);
}
And then in main file invoked it like this:
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <sys/time.h>
#include "../timer.h"
#define BUF_SIZE 4096
#define TIMEVAL_TO_MICROSECONDS(tv) ((long long)((tv).tv_sec * 1000000 + (tv).tv_usec))
#define GET_TIME_PASSED(start, now) ((TIMEVAL_TO_MICROSECONDS(now) - TIMEVAL_TO_MICROSECONDS(start)))
void progress_bar(int percent, int bar_len)
{
char buf[BUF_SIZE];
int inside = bar_len - 2;
int filled = inside * percent / 100;
int not_filled = inside - filled;
assert(percent <= 100);
assert(bar_len < BUF_SIZE);
buf[0] = '[';
memset(buf + 1, '#', filled);
memset(buf + 1 + filled, '-', not_filled);
buf[bar_len - 1] = ']';
buf[bar_len] = 0;
printf("\r%s %d%%", buf, percent);
fflush(stdout);
}
void timer_ontime(void *data)
{
struct timer *t = data;
puts("");
puts("That's all folks!");
timer_exit(t);
}
void timer_update(void *data)
{
struct timer *t = data;
struct timeval now;
long long passed;
int percent;
gettimeofday(&now, NULL);
passed = GET_TIME_PASSED(*(t->start), now);
percent = passed * 100 / (t->interval->tv_sec * 1000000);
progress_bar(percent, 50);
}
int main(int argc, char **argv)
{
struct timer *t;
int seconds;
int check;
if(argc != 2)
{
fprintf(stderr, "Usage: %s <seconds>\n", argv[0]);
return 1;
}
check = sscanf(argv[1], "%d", &seconds);
if(check != 1)
{
fprintf(stderr, "Couldn't parse number of seconds\n");
return 1;
}
t = my_timer_create();
if(t == NULL)
{
fprintf(stderr, "Couldn't create timer\n");
return 1;
}
timer_set_interval(t, seconds, 0);
timer_set_ontime_func(t, timer_ontime);
timer_set_update_func(t, timer_update);
timer_start(t);
printf("Started timer(%d seconds)\n", seconds);
pthread_join(t->thread_id, NULL);
}
Then i run it with:
[udalny#bulba test]$ time ./timer_check 3
Started timer(3 seconds)
[###############################################-] 99%
That's all folks!
./timer_check 3 0.48s user 1.22s system 56% cpu 3.002 total
So as you can see it takes 56% CPU time. Why so much?
It updates only twice per second(DEFAULT_CALLBACK is 500000 microseconds). And all
other time it is sleeping.
How could I change it so it takes less?
Also I would appreciate any tips on the code.
Your program spends most of its time in timer_count, looping busily - if you add a simple printf before your select:
printf("?\n");
check = select(t->ls + 1, &readfds, NULL, NULL, &timeout);
and run ./timer_check 3 | wc -l you should get millions of lines - meaning the CPU hard-loops on this loop. This is because of the way you initialize your timeout:
if(t->update_interval)
memcpy(&timeout, t->update_interval, sizeof(*(t->update_interval)));
this actually sets your timeout to zero - because you never initialized your t->update_interval in main. This effectively turns your loop into a busy loop.
Add the following line to your main function to fix this:
timer_set_update_interval(t, seconds, 0);
after which you get your desired behavior:
Started timer(3 seconds)
[################################################] 100%
That's all folks!
0.00user 0.00system 0:03.00elapsed 0%CPU (0avgtext+0avgdata 1932maxresident)k
0inputs+0outputs (0major+77minor)pagefaults 0swaps
I am trying to solve the producer consumer problem using pthreads and semaphores. At the moment, neither of the threads seem to execute and even main isn't printing out a printf, it seems like the process is waiting for input. (so all that happens is, blinking cursor, then I press ctrl+c to end the process because nothing is happening). I have tested get_rand_num and that works. I am compiling with clang -Wall -std=c99 -lpthread -o randnumgen randnumgen.c
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
#include "sema.c"
typedef struct buffer {
uint64_t *buffer;
int max_size;
int min_fill_lvl;
uint64_t *first;
uint64_t *last;
int size;
semaphore produce;
semaphore consume;
} buffer;
void *producer();
void *consumer();
uint64_t get_rand_num();
void init_buffer();
void cleanup_buffer();
void put_buffer();
uint64_t get_buffer();
int exit1=0;
buffer buf;
int main(){
initialize(&buf.produce, 0);
initialize(&buf.consume, 0);
pthread_t producerThread;
pthread_t consumerThread;
printf("test");
pthread_create(&producerThread, NULL, producer, (void *) &buf);
pthread_create(&consumerThread, NULL, consumer, (void *) &buf);
vacate(&buf.produce);
pthread_join(producerThread, NULL);
pthread_join(consumerThread, NULL);
return 1;
}
void *producer(buffer *buf){
printf("in producer");
init_buffer(&buf, 2, 1);
while (1){
procure(&buf->produce);
uint64_t ret = get_rand_num();
put_buffer(&buf, ret);
vacate(&buf->consume);
}
cleanup_buffer(&buf);
pthread_exit(NULL);
}
void *consumer(buffer *buf){
printf("in consumer");
while (1){
procure(&buf->consume);
uint64_t ret = get_buffer(&buf);
printf("%i", (int) ret);
vacate(&buf->produce);
}
pthread_exit(NULL);
}
uint64_t get_rand_num(){
FILE *rand = NULL;
rand = fopen("/dev/random", "r");
uint64_t num;
//static const size_t size = sizeof(uint64_t);
fread(&num, sizeof(num), 1, rand); //returns -1 if fails i believe
//printf("%i\n", (int) num);
return num;
}
void init_buffer(buffer *buf, int max, int min){
buf->buffer = malloc(sizeof(uint64_t) * max);
buf->size = 0;
buf->min_fill_lvl = min;
buf->max_size = max;
}
void cleanup_buffer(buffer *buf){
free(&buf->buffer);
}
void put_buffer(buffer *buf, uint64_t *num){
if (buf->size < buf->max_size){
*(buf->last++) = *num;
buf->size++;
}
printf("successfully placed num in buffer");
}
uint64_t get_buffer(buffer *buf){
if ((buf->size - 1) <= buf->min_fill_lvl){
buf->size--;
int ret = *buf->first;
buf->first++;
return ret;
}
return 0;
}
This is my semaphore code:
// semaphore setup
void initialize(semaphore *sp, int startVal){
pthread_mutex_init(&sp->lock, NULL);
sp->vacancy = startVal; //starting value for semaphore
pthread_cond_init(&sp->condition, NULL);
}
//destroys semaphore
void destruct(semaphore *sp){
pthread_mutex_destroy(&sp->lock);
pthread_cond_destroy(&sp->condition);
}
//waits until semaphore is available
void procure(semaphore *sp){
pthread_mutex_lock(&sp->lock);
while(sp->vacancy <= 0){
pthread_cond_wait(&sp->condition, &sp->lock);
}
sp->vacancy--;
pthread_mutex_unlock(&sp->lock);
}
//increments vacancy value signalling that a position has been freed
void vacate(semaphore *sp){
pthread_mutex_lock(&sp->lock);
sp->vacancy++;
pthread_cond_signal(&sp->condition);
pthread_mutex_unlock(&sp->lock);
}
Please help the Synchronization
I have to make this program to performe sequentially manner using
in threads( ex) thread1 performe and thread2 perforem and so on)
But it should be implemented only with Semaphore. I put in the wait(), Signal()
function to be act like semaphore(but not working)
You just need to see the pthread_join, and thread_work part
(the main purpose of this program : make 20threads and synchorinize them with semaphore)
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
#define num_thread 20
char str[11];
void *thread_work(void *tid); //Main body of Thread working
void generate_str(int n); //Create random character string
void str_sort(void); //Sorting the generated string into alpabet manner
void check_sort(void); //Check about "Is the sorting is right"
void print_time(struct timespec *myclock); //print the time interval of thread work
void print_time_program(struct timespec *myclock);
void wait(void); //I put in these two function to be act like semaphore
void Signal(void); //But it does't work
int S=1;
int main(void)
{
pthread_t tid[num_thread];
int rc;
int t;
struct timespec myclock[4];
srand(time(NULL));
clock_gettime(CLOCK_REALTIME, &myclock[2]);
for(t=0; t<num_thread; t++)
pthread_create(&tid[t], NULL, thread_work, (void *)&t);
for(t=0; t<num_thread; t++)
pthread_join(tid[t], NULL);
clock_gettime(CLOCK_REALTIME, &myclock[3]);
print_time_program(myclock);
return 0;
}
void *thread_work(void *t)
{
do
{
wait(); //Entry Section
//CRITICAL SECTION START
struct timespec myclock[2];
clock_gettime(CLOCK_REALTIME, &myclock[0]);
int n = *((int *)t);
printf("########## Thread #%d starting ########## \n", n);
generate_str(n);
str_sort();
check_sort();
printf("########## Thread #%d exiting ##########\n", n);
clock_gettime(CLOCK_REALTIME, &myclock[1]);
print_time(myclock);
//CRITICAL SECTION END
Signal();
pthread_exit(NULL);
}while (1);
}
void str_sort(void)
{
int temp;
int i, j;
for(i=0; i<9; i++)
for(j=0; j<9-i; j++)
{
if(str[j]>str[j+1])
{
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
printf("Sorted string : %s ", str);
}
void generate_str(int n)
{
int i;
int num;
srand(n);
for(i=0; i<10; i++)
{
num = (97+rand()%26);
str[i]=num;
}
str[10]='\0';
printf("Initialized string : %s \n", str);
}
void check_sort(void)
{
int i;
int count=0;
for(i=0; i<9; i++)
{
if(str[i]>str[i+1])
count++;
}
if(count != 0)
printf("[X] FALSE \n");
else
printf("[O] TRUE \n");
}
void print_time(struct timespec *myclock)
{
long delay, temp, temp_n, sec;
sec = myclock[0].tv_sec % 60;
printf("Thread Starting Time : %ld.%ld second\n", sec, myclock[0].tv_nsec);
sec = myclock[1].tv_sec % 60;
printf("Thread Exiting Time : %ld.%ld second\n", sec, myclock[1].tv_nsec);
if (myclock[1].tv_nsec >= myclock[0].tv_nsec)
{
temp = myclock[1].tv_sec - myclock[0].tv_sec;
temp_n = myclock[1].tv_nsec - myclock[0].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
else
{
temp = myclock[1].tv_sec - myclock[0].tv_sec - 1;
temp_n = 1000000000 + myclock[1].tv_nsec - myclock[0].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
printf("Thread Working Time : %ld nano second", delay);
delay = delay / 1000000;
printf("(%ld ms)\n\n\n", delay);
return ;
}
void print_time_program(struct timespec *myclock)
{
long delay, temp, temp_n, sec;
sec = myclock[2].tv_sec % 60;
printf("Program Starting Time : %ld.%ld second\n", sec, myclock[2].tv_nsec);
sec = myclock[3].tv_sec % 60;
printf("Program Exiting Time : %ld.%ld second\n", sec, myclock[3].tv_nsec);
if (myclock[3].tv_nsec >= myclock[2].tv_nsec)
{
temp = myclock[3].tv_sec - myclock[2].tv_sec;
temp_n = myclock[3].tv_nsec - myclock[2].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
else
{
temp = myclock[3].tv_sec - myclock[2].tv_sec - 1;
temp_n = 1000000000 + myclock[3].tv_nsec - myclock[2].tv_nsec;
delay = 1000000000 * temp + temp_n;
}
printf("Program Total Working Time : %ld nano second", delay);
delay = delay / 1000000;
printf("(%ld ms)\n\n\n", delay);
return ;
}
void wait(void)
{
while( S <= 0);
S--;
}
void Signal(void)
{
S++;
}
Here is a working example of how to make threads execute one after another using a semaphore (Linux/Cygwin pthreads):
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_THREADS 5
/* global thread exit control flag */
volatile uint32_t g_ExitFlag = 0;
/* global thread execution control semaphore */
sem_t g_Sem;
/* the thread function */
void *ThreadFunc(void *pContext)
{
uint32_t tid = (uint32_t)pContext;
/* main thread loop */
while (g_ExitFlag == 0)
{
/* wait for semaphore to be signalled */
sem_wait(&g_Sem);
printf("Thread %d running.\n", tid);
}
printf("Thread %d exiting.\n", tid);
return NULL;
}
int main(int argc, char *argv[])
{
uint32_t i = 0;
pthread_t th;
/* suppress warnings */
(void)argc;
(void)argv;
/* initialize the semaphore */
sem_init(&g_Sem, 0, 0);
/* create and detach several threads */
for (i = 0; i < NUM_THREADS; ++i)
{
pthread_create(&th, NULL, ThreadFunc, (void *)i);
pthread_detach(th);
}
/* run each thread four times and exit */
for (i = 0; i < (NUM_THREADS * 4); ++i)
{
if (i == 15)
{
g_ExitFlag = 1;
}
/* release a thread to execute */
sem_post(&g_Sem);
sleep(1);
}
return 0;
}
It should be straightforward for you to integrate that kind of functionality into your program.
Getting seg-fault when I run this code. I commented where I'm getting the seg-fault (in handler() function). I'm not sure, may be I'm wrapping data twice that's why or what's the problem? It's printing correctly till "start_timer" method.
#include <time.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
typedef struct _data{
char *name;
}data;
struct timer_list{
void* timer_data;
unsigned long expires;
void (*function)(sigval_t);
};
volatile long int second = 0;
void handler(sigval_t val)
{
data *data_handler = val.sival_ptr;
printf("Handler: address of data: %p\n", data_handler);
printf("Handler: address of &data_handler->name: %p\n", &data_handler->name);
printf("Handler entered with value :%s\n", data_handler->name); `**//**SEG-FAULT HERE****`
}
void timer_handler(union sigval val)
{
printf(" ----- Seconds: %ld\n", ++second);
}
/* start timer with all we got as data is timer */
void start_timer(struct timer_list *timer)
{
printf("\nStart_timer...: Timer->data address: %p\n", timer->timer_data);
data *data_handler = timer->timer_data;
printf("Start_timer...: entered with value :%s\n", data_handler->name);
int Ret;
pthread_attr_t attr;
pthread_attr_init( &attr );
//pthread_t tid;
struct sched_param parm;
parm.sched_priority = 255;
pthread_attr_setschedparam(&attr, &parm);
struct sigevent sig;
sigval_t val;
val.sival_ptr = timer->timer_data;
sig.sigev_notify = SIGEV_THREAD;
sig.sigev_notify_function = timer->function;
// sig.sigev_value.sival_int = val;
sig.sigev_value = val;
sig.sigev_notify_attributes = &attr;
data *data_handler1 = (data *)val.sival_ptr;
printf("From sigval...: handler_data address: %p\n", data_handler1);
printf("From sigval...: handler_data->name address: %p\n", &data_handler1->name);
printf("From sigval...: Handler entered with value :%s\n", data_handler1->name);
//create a new timer.
timer_t timerid;
Ret = timer_create(CLOCK_REALTIME, &sig, &timerid);
if (Ret == 0)
{
struct itimerspec in, out;
in.it_value.tv_sec = timer->expires;
in.it_value.tv_nsec = 0;
in.it_interval.tv_sec = 0;
in.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &in, &out);
}
}
/* Start_timer_on: wrapping up data into one timer structure, and starting timer */
void start_timer_on(data timer_data, unsigned long expires)
{
struct timer_list *timer = (struct timer_list *)malloc(sizeof(struct timer_list)); //Problem was here ... forgot to use malloc
timer->timer_data = &timer_data;
printf("\nTimer->data address: %p\n", &timer_data);
timer->function = handler;
timer->expires = expires;
start_timer(timer);
}
/* Main */
void main()
{
data handler_data1 = {"Handler Data 1"};
//data handler_data2 = {"Handler Data 2"};
//void *data1 = &handler_data1;
//void *data2 = &handler_data2;
pthread_attr_t attr;
pthread_attr_init( &attr );
struct sched_param parm;
parm.sched_priority = 255;
pthread_attr_setschedparam(&attr, &parm);
struct sigevent sig;
sig.sigev_notify = SIGEV_THREAD;
sig.sigev_notify_function = timer_handler;
sig.sigev_notify_attributes = &attr;
//create a new timer - clock.
timer_t timerid;
timer_create(CLOCK_REALTIME, &sig, &timerid);
struct itimerspec in, out;
in.it_value.tv_sec = 1;
in.it_value.tv_nsec = 0;
in.it_interval.tv_sec = 1;
in.it_interval.tv_nsec = 0;
printf("*** *** *** Main clock starts *** *** ***\n");
timer_settime(timerid, 0, &in, &out);
printf("***** Start timer for data1 for 2 sec *****\n");
start_timer_on(handler_data1, 2);
// printf("***** Start timer for data1 for 5 sec *****\n");
// start_timer(data2, 5);
sleep(20);
}
This might be the problem. In the code below, timer_data is local to function start_timer_on. The object is destroyed as soon as the function exits. So, when accessing the name in handler, it will segfault.
void start_timer_on(data timer_data, unsigned long expires)
{
struct timer_list *timer;
timer->timer_data = &timer_data;
printf("\nTimer->data address: %p\n", &timer_data);
timer->function = handler;
timer->expires = expires;
start_timer(timer);
}
You should use void start_timer_on(data *timer_data, unsigned long expires), so that the data is not freed until main exits.
Hey, I've got just a small problem related to pthread_cond_timedwait. I've tried implementing it into this piece of code. I can't get the arguments right for timedwait, because I am not too sure what I'm doing. If anyone could point me in the right direction it would be much appreciated!
#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t timeLock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;
int timeIndex = 0;
time_t times[100];
void print_time(time_t tt)
{
char buf[80];
struct tm* st = localtime(&tt);
strftime(buf, 80, "%c", st);
printf("Call me on: ");
printf("%s\n", buf);
}
void *add_time(time_t tt){
if(timeIndex == 100)
timeIndex = 0;
struct timespec ts;
times[timeIndex] = tt;
timeIndex++;
ts.tv_sec = tt;
print_time(tt); // print element
}
void * call_time()
{
while(1)
{
const time_t c_time = time(NULL);
int i;
for(i = 0; i <= 100; i++)
{
if(c_time == times[i])
{
printf("\nWake me up!\n");
times[i] = 0;
}
}
}
}
void * newTime()
{
while(1)
{
time_t f_time;
f_time = time(NULL);
srand ( time(NULL) );
f_time += rand()%100;
add_time(f_time);
sleep(1);
}
}
int main(void)
{
pthread_t timeMet;
pthread_t time;
pthread_create(&time, NULL, newTime, NULL);
pthread_create(&timeMet, NULL, call_time, NULL);
pthread_join(time, NULL);
pthread_join(timeMet, NULL);
return 0;
}