/*
 * $RCSfile: threads.c,v $
 * $Revision: 32.10 $
 *
 * (C) Copyright ParaSoft Corporation 1998.  All rights reserved.
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ParaSoft
 * The copyright notice above does not evidence any
 * actual or intended publication of such source code.
 *
 * $Date: 2001/09/21 17:22:02 $
 *
 * Comments:
 *
 * This example demonstrates WRITE_BAD_INDEX, WRITE_UNI_MEM, LEAKSCOP and
 * WRITE_OVERFLOW happening in four different threads ...
 *
 * This example would need changes to compile with older drafts
 * of the POSIX standard.
 */

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>


static char rcsid[]=
"@(#)$RCSfile: threads.c,v $ $Revision: 32.10 $ $Date: 2001/09/21 17:22:02 $";

#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C 
#endif

EXTERN_C void *first_thread(void *);
EXTERN_C void *second_thread(void *);
EXTERN_C void *third_thread(void *);
EXTERN_C void *fourth_thread(void *);

main()
{
  pthread_t       thread1, thread2, thread3, thread4;
 
#if defined(DRAFT4)
  pthread_create(&thread1,  pthread_attr_default, 
	         (pthread_startroutine_t) first_thread, 0);
  pthread_create(&thread2,  pthread_attr_default, 
                 (pthread_startroutine_t) second_thread, 0);
  pthread_create(&thread3,  pthread_attr_default, 
                 (pthread_startroutine_t) third_thread, 0);
  pthread_create(&thread4,  pthread_attr_default, 
                 (pthread_startroutine_t) fourth_thread, 0);
#elif defined(_AIX_PTHREADS_D7)
  /* cc_r7 creates detached threads */
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);

  pthread_create(&thread1, &attr, first_thread, 0);
  pthread_create(&thread2, &attr, second_thread, 0);
  pthread_create(&thread3, &attr, third_thread, 0);
  pthread_create(&thread4, &attr, fourth_thread, 0);

  pthread_attr_destroy(&attr);
#else
  pthread_create(&thread1, 0, first_thread, 0);
  pthread_create(&thread2, 0, second_thread, 0);
  pthread_create(&thread3, 0, third_thread, 0);
  pthread_create(&thread4, 0, fourth_thread, 0);
#endif
  
  pthread_join(thread1, 0);
  pthread_join(thread2, 0);
  pthread_join(thread3, 0);
  pthread_join(thread4, 0);

  return 0;
}

void *first_thread(void *times)
{
    int j, x;
  
    printf("*\n"); 
    for (j = 0; j < 400; j++)  {
      x = x + 1; /* READ_UNINIT_MEM */
    }
    return (void *)0;
}

void *second_thread(void *times)
{
    int *leak;
  
    printf("**\n"); 
    leak = (int *) malloc(1);
    return (void *)0; /* LEAK_SCOPE */
}

void *third_thread(void *times) 
{
    int j;
    int _x_guard1[16], x[16], _x_guard2[16];

    printf("***\n");
    for (j = 0; j < 17; j++) {
	x[j] = j; /* WRITE_BAD_INDEX */
    }
    return (void *)0;
}

int _x_guard1[16];
int x[16];
int _x_guard2[16];
void *fourth_thread(void *times)
{
    int j, *ip;

    printf("****\n");
    for (j = 0; j < 17; j++) { 
	x[j] = j; /* WRITE_BAD_INDEX */
    }
    ip = x;
    ip += 16;
    *ip = j;  /* WRITE_OVERFLOW */
    return (void *)0;
}