#include <stdio.h>
#include <unistd.h> 
#include <signal.h>
#include <stdlib.h> 
static int running = 1;
static pthread_t thread;
static int thread_ret_val;
static void* __thread_func(void* arg)
{
        int received_argument = *(int*)arg;
        printf("thread received argument value: %d\n",received_argument);
        printf("thread has properties: ");
        while(running){
                sleep(1);
                printf("thread running! press ctrl-c to exit\n");
        }
        printf("exiting thread\n");
        thread_ret_val=received_argument;
        return (void*)&thread_ret_val;
}
static void __signal_handler(__attribute__ ((unused)) int dummy)
{
        running=0;
        return;
}
static void __print_usage(void)
{
        fprintf(stderr, "Usage:\n");
        #define fpe(msg) fprintf(stderr, "\t%s", msg);          
        fpe("-p <policy><pri> Set scheduling policy and priority\n");
        fpe("                 <policy> can be\n");
        fpe("                     f  SCHED_FIFO\n");
        fpe("                     r  SCHED_RR\n");
        fpe("                     o  SCHED_OTHER\n");
        fpe("-d               Use default thread attributes object\n");
        fpe("-h               Print this help message\n");
        fpe("\n");
        fpe("For example, to run with SCHED_FIFO at priority 50 run:\n");
        fpe(" rc_test_pthread -p f50\n")
        #undef fpe
        return;
}
static int __get_policy(char p, int *policy)
{
        switch (p) {
        case 'f': *policy = SCHED_FIFO;     return 0;
        case 'r': *policy = SCHED_RR;       return 0;
        case 'o': *policy = SCHED_OTHER;    return 0;
        default:
                fprintf(stderr, "invalid policy\n");
                return -1;
        }
}
int main(int argc, char *argv[])
{
        int ret, opt;
        int policy = SCHED_OTHER;
        int priority = 0;
        char *attr_sched_str;
        int use_default=0;
        int use_custom=0;
        int arg=42; 
        void* retval; 
        while((opt = getopt(argc, argv, "p:dh")) != -1){
                switch (opt) {
                case 'p':
                        attr_sched_str = optarg;
                        use_custom = 1;
                        break;
                case 'd':
                        use_default = 1;
                        break;
                case 'h':
                        __print_usage();
                        break;
                default:
                        fprintf(stderr,"invalid option\n");
                        __print_usage();
                        return -1;
                }
        }
        if(use_custom && use_default){
                fprintf(stderr, "ERROR: can't use custom and default properties\n");
                return -1;
        }
        if(!use_custom && !use_default){
                fprintf(stderr, "one argument must be given\n");
                __print_usage();
                return -1;
        }
        if(use_custom){
                if(__get_policy(attr_sched_str[0], &policy)){
                        __print_usage();
                        return -1;
                }
                priority = strtol(&attr_sched_str[1], NULL, 0);
        }
        
        signal(SIGINT, __signal_handler);
        
        printf("starting thread with argument: %d\n",arg);
                fprintf(stderr, "failed to start thread\n");
                return -1;
        }
        
        while(running)  sleep(1);
        
        if(ret==1) fprintf(stderr,"joining thread timed out\n");
        printf("pthread returned:%d\n",*(int*)retval);
        return 0;
}