diff --git a/lab4/src/threads/threading b/lab4/src/threads/threading new file mode 100755 index 0000000..5ae8700 Binary files /dev/null and b/lab4/src/threads/threading differ diff --git a/lab4/src/threads/threading.cpp b/lab4/src/threads/threading.cpp new file mode 100644 index 0000000..6e02857 --- /dev/null +++ b/lab4/src/threads/threading.cpp @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include "important.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +int current_index = 0; +int sum; +struct image_t* input_image; +struct image_t* smoother; +struct image_t* details; +struct image_t* sharp; +int a = 1; + +int lock1 = 0; // initial lock set +int lock2 = 1; // initial lock set +int lock3 = 0; // initial lock set +int lock4 = 1; // initial lock set + +int pt = 1; +int pt1 = 1; + +void* S1_smoothen(void* thread_number) +{ + int my_number = *(int *)thread_number; + //cout << input_image->width << input_image->height << " " << input_image->image_pixels << endl; + int width = input_image->width; + int height = input_image->height; + + // memory allocation + // struct image_t* smoother = new struct image_t; + for(pt = 1; pt <= 1000; ++pt) { + while(__sync_lock_test_and_set(&lock1,1)); + printf("thread number : %d\tindex : %d\n", my_number, pt); + for(int i = 1; i < height-1; i++) + { + for(int j = 1; j < width-1; j++) + { + for(int k = 0; k < 3; k++) + { + //image->image_pixels[i][j][k] = val; + // edge cases + if(i == 0 && j == 0) { // i-1 and j - 1 doesnt exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i][j][k] / 9+ input_image->image_pixels[i][j+1][k] / 9 + input_image->image_pixels[i+1][j][k] / 9 + input_image->image_pixels[i+1][j+1][k] / 9); + + } + else if(i == height - 1 && j == 0) { // i+1 and j-1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i-1][j][k] / 9 + input_image->image_pixels[i-1][j+1][k] / 9+ input_image->image_pixels[i][j][k] / 9+ input_image->image_pixels[i][j+1][k] / 9); + } + + else if(i == 0 && j == width - 1) { // i-1 and j+1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i][j-1][k] / 9 + input_image->image_pixels[i][j][k] / 9+ input_image->image_pixels[i+1][j-1][k] / 9 + input_image->image_pixels[i+1][j][k] / 9); + } + else if(i == height - 1 && j == width - 1) { // i+1 and j+1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i-1][j-1][k] / 9 + input_image->image_pixels[i-1][j][k] / 9 + input_image->image_pixels[i][j-1][k] / 9 + input_image->image_pixels[i][j][k] / 9); + } + else if (i == 0) { // i - 1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i][j-1][k] / 9 + input_image->image_pixels[i][j][k] / 9+ input_image->image_pixels[i][j+1][k] / 9+ input_image->image_pixels[i+1][j-1][k] / 9+ input_image->image_pixels[i+1][j][k] / 9+ input_image->image_pixels[i+1][j+1][k] / 9); + } + + else if(j == 0) { // j -1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i-1][j][k] / 9+ input_image->image_pixels[i-1][j+1][k] / 9+ input_image->image_pixels[i][j][k] / 9+ input_image->image_pixels[i][j+1][k] / 9+ input_image->image_pixels[i+1][j][k] / 9+ input_image->image_pixels[i+1][j+1][k]/ 9); + } + + else if(i == height - 1) { // i+1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i-1][j-1][k] / 9+ input_image->image_pixels[i-1][j][k] / 9+ input_image->image_pixels[i-1][j+1][k] / 9+ input_image->image_pixels[i][j-1][k] / 9+ input_image->image_pixels[i][j][k] / 9+ input_image->image_pixels[i][j+1][k]/ 9); + } + else if(j == width - 1) { // j + 1 does not exist + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i-1][j-1][k] / 9+ input_image->image_pixels[i-1][j][k] / 9+ input_image->image_pixels[i][j-1][k] / 9+ input_image->image_pixels[i][j][k]/ 9 + input_image->image_pixels[i+1][j-1][k] / 9+ input_image->image_pixels[i+1][j][k] / 9); + } + else { + smoother->image_pixels[i][j][k] = ( input_image->image_pixels[i-1][j-1][k] / 9 + input_image->image_pixels[i-1][j][k] / 9 + input_image->image_pixels[i-1][j+1][k]/9 + input_image->image_pixels[i][j-1][k]/9 + input_image->image_pixels[i][j][k] / 9 + input_image->image_pixels[i][j+1][k] / 9 + input_image->image_pixels[i+1][j-1][k] / 9 + input_image->image_pixels[i+1][j][k] / 9 + input_image->image_pixels[i+1][j+1][k] / 9); + + } + } + } + } + __sync_lock_release(&lock2); + __sync_lock_release(&lock1); + + } + return nullptr; +} + +// atomic_flag lock_stream2 = ATOMIC_FLAG_INIT; // initial lock set + +void* S2_find_details(void *thread_number) +{ + + int my_number = *(int *)thread_number; + int width = input_image->width; + int height = input_image->height; + for(pt1 = 0; pt1 <= 1000; ++pt1) { + while(__sync_lock_test_and_set(&lock2,1)); + while(__sync_lock_test_and_set(&lock1,1)); + while(__sync_lock_test_and_set(&lock3,1)); + // while(lock_stream1.test_and_set()); + // while(lock_stream2.test_and_set()); + printf("thread number : %d\tindex : %d\n", my_number, pt1); + for(int i = 1; i < height-1; i++) + { + for(int j = 1; j < width-1; j++) + { + for(int k = 0; k < 3; k++) + { + details->image_pixels[i][j][k] = max(0, (input_image->image_pixels[i][j][k] - smoother->image_pixels[i][j][k])); + } + } + } + __sync_lock_release(&lock1); + __sync_lock_release(&lock4); + __sync_lock_release(&lock3); + + if(pt >= 1000) + { + __sync_lock_release(&lock2); + } + + + } + + return nullptr; +} + +void* S3_sharpen(void* thread_number) +{ + int my_number = *(int *)thread_number; + int width = input_image->width; + int height = input_image->height; + for(int pt2 = 1; pt2 <= 1000; ++pt2) { + // while(lock_stream2.test_and_set()); + while (__sync_lock_test_and_set(&lock4, 1)); + while (__sync_lock_test_and_set(&lock3, 1)); + + printf("thread number : %d\tindex : %d\n", my_number, pt2); + for(int i = 1; i < height-1; i++) + { + for(int j = 1; j < width-1; j++) + { + for(int k = 0; k < 3; k++) + { + sharp->image_pixels[i][j][k] = min(255, input_image->image_pixels[i][j][k] + details->image_pixels[i][j][k]) * a; + } + } + } + __sync_lock_release(&lock3); + + if(pt1 >= 1000) + { + __sync_lock_release(&lock4); + } + } + + return nullptr; +} + + +int main(int argc, char *argv[]) { + + pthread_t thread1, thread2, thread3; + int iret1, iret2, iret3; + int thread_number1 = 1, thread_number2 = 2, thread_number3 = 3; + + input_image = read_ppm_file(argv[1]); + + smoother = new struct image_t; + details = new struct image_t; + sharp = new struct image_t; + + int width = input_image->width; + int height = input_image->height; + + // memory allocation for global smoothened image ------------ threads share same global variable + smoother->height = height; + smoother->width = width; + smoother->image_pixels = new uint8_t**[height]; + for(int i = 0; i < height; i++) + { + smoother->image_pixels[i] = new uint8_t*[width]; + for(int j = 0; j < width; j++) + smoother->image_pixels[i][j] = new uint8_t[3]; + } + + // memory allocation for global detailed image + details->height = height; + details->width = width; + details->image_pixels = new uint8_t**[height]; + + for(int i = 0; i < height; i++) + { + details->image_pixels[i] = new uint8_t*[width]; + for(int j = 0; j < width; j++) + details->image_pixels[i][j] = new uint8_t[3]; + } + + // memory allocation for global sharper image + sharp->height = height; + sharp->width = width; + sharp->image_pixels = new uint8_t**[height]; + + for(int i = 0; i < height; i++) + { + sharp->image_pixels[i] = new uint8_t*[width]; + for(int j = 0; j < width; j++) + sharp->image_pixels[i][j] = new uint8_t[3]; + } + + + /* Create independent threads each of which will execute function */ + iret1 = pthread_create(&thread1, NULL, S1_smoothen, &thread_number1); + if(iret1) + { + fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1); + exit(EXIT_FAILURE); + } + iret2 = pthread_create(&thread2, NULL, S2_find_details, &thread_number2); + if(iret2) + { + fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2); + exit(EXIT_FAILURE); + } + iret3 = pthread_create(&thread3, NULL, S3_sharpen, &thread_number3); + if(iret3) + { + fprintf(stderr,"Error - pthread_create() return code: %d\n",iret3); + exit(EXIT_FAILURE); + } + + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + pthread_join(thread3, NULL); + + // printf("\nsum = %d\n", sum); + printf("ttis"); + exit(EXIT_SUCCESS); + return 1; +}