0

Problem Statement:

"Larry, Moe, and Curly are planting seeds. Larry digs the holes. Moe then places a seed in each hole. Curly then fills the hole up. There are several synchronization constraints:

  • Moe cannot plant a seed unless at least one empty hole exists, but Moe does not care how far Larry gets ahead of Moe.
  • Curly cannot fill a hole unless at least one hole exists in which Moe has planted a seed, but the hole has not yet been filled. Curly does not care how far Moe gets ahead of Curly.
  • Curly does care that Larry does not get more than MAX holes ahead of Curly. Thus, if there are MAX unfilled holes, Larry has to wait.
  • There is only one shovel with which both Larry and Curly need to dig and fill the holes, respectively.

Design, implement and test a solution for this IPC problem, which represent Larry, Curly, and Moe. Use semaphores as the synchronization mechanism."

I've typed up a program from some pseudocode that I was given, but I'm getting the error:

project2part3.c:13:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion] 
 #define MAX 5
             ^
project2part3.c:22:18: note: in expansion of macro 'MAX'
 sem_t unfilled = MAX;
                   ^
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#define MAX 5

void *larry();
void *moe();
void *curly();

pthread_mutex_t shovel = PTHREAD_MUTEX_INITIALIZER;
sem_t empty;
sem_t seeded;
sem_t unfilled;

int main(){
    pthread_t ltid;
    pthread_t mtid;
    pthread_t ctid;
    //initializing the semaphores
    sem_init(&empty, 0, 0);
    sem_init(&seeded, 0, 0);
    sem_init(&unfilled, 0, 0);

    pthread_create(&ltid, NULL, larry, NULL);  //create the larry thread
    pthread_create(&mtid, NULL, moe, NULL);  //create the moe thread
    pthread_create(&ctid, NULL, curly, NULL);  //create the curly thread

    pthread_join(ltid,NULL);
    pthread_join(mtid,NULL);
    pthread_join(ctid,NULL);
}

void *larry(){
    while(1){
        sem_wait(unfilled);
        sem_wait(shovel);
        //Dig the hole
        printf("Digging");
        sem_post(shovel);
        sem_post(empty);
    }
}

void *moe(){
    while(1){
        sem_wait(empty);
        //Seed the hole
        printf("Seeding");
        sem_post(seeded);
    }
}

void *curly(){
    while(1){
        sem_wait(seeded);
        sem_wait(shovel);
        //Fill the hole
        printf("Filling");
        sem_post(shovel);
        sem_post(unfilled);
    }
}
Tangwheeler
  • 207
  • 1
  • 11
  • 1
    Which line is the error pointing to? Show the full error statement – sabbahillel Mar 04 '16 at 15:01
  • Functions are declared as `void*`, but are not returning any values. Fishy. Also `main` is not returning anything. Also functions not taking parameters should be declared as `(void)`. I would say you should get much more warnings. – Eugene Sh. Mar 04 '16 at 15:03
  • `sem_t unfilled = MAX;` That's not how you initialize a semaphore... – Dark Falcon Mar 04 '16 at 15:04
  • It's like the compiler is telling you the exact location and the exact error and you are asking "what's wrong"? – Eugene Sh. Mar 04 '16 at 15:09
  • @EugeneSh., a `main` with no explicit return implicitly returns 0. It's a wonderful feature that saves me about 10 key strokes every time I write a `main`. – Eran Mar 04 '16 at 15:11
  • @eran I *think* that is not true. The value returned without an explicit `return` statement is undefined. **Update:** http://stackoverflow.com/questions/3727051/why-does-a-main-function-without-a-return-statement-return-value-12 – Eugene Sh. Mar 04 '16 at 15:13
  • @EugeneSh. It really returns 0 as per the standard, but it's **not** implicitly returning `EXIT_SUCCESS`, which - of different from 0 - could cause issues. – Daniel Jour Mar 04 '16 at 15:17
  • @DanielJour Well, that's tricky point. I wouldn't save 10 keystrokes on it. – Eugene Sh. Mar 04 '16 at 15:20
  • @EugeneSh. I'm not that lazy, too. But some ... well, it's a nice topic for a flame war :D – Daniel Jour Mar 04 '16 at 15:22
  • the posted code when fed to the compiler causes the compiler to output 20 error and warning statements. (using `gcc -c -Wall -Wextra -Wconversion -pedantic -std=gnu99 filename.c -o filename.o -I. -I/usr/include` ) – user3629249 Mar 05 '16 at 21:24

1 Answers1

4
sem_t shovel = 1; // Note: Is a lock in the updated question code
sem_t empty = 0;
sem_t seeded = 0;
sem_t unfilled = MAX;

That's not how you initialise semaphores. They're complex things, not just counters that can be assigned to. That's the reason there's the function sem_init, which you're using, but not correctly. Read up on it in a reference of your choice.

IIRC sem_t is a typedef similar to

typedef struct whatever * sem_t;

Thus each of the above lines initialises a pointer from an integer.

Furthermore, your functions should return what you declare them to return. This is especially true for the functions used for the threads: They (need to) declare that they return a void pointer, so (if you don't have anything meaningful to return) just use

return NULL;

at the end of reach of these.

Moreover:

pthread_create(&btid, NULL, larry, NULL);  //create the larry thread
pthread_create(&btid, NULL, moe, NULL);  //create the moe thread
pthread_create(&btid, NULL, curly, NULL);  //create the curly thread

You want these calls to different thread_ts, not all to the same (btid).

Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
  • note: the posted code is declaring `shovel` as a pthread_mutex, NOT as a semaphore, so every reference to shovel should use the `pthread_mutex_lock()` or `pthread_mutex_unlock()` functions not `semwait()` and not `sempost()` – user3629249 Mar 05 '16 at 21:30
  • @user3629249 Indeed, I added a note. I'm planning on keeping it in as it resembles the original question's code and lines up better with the rest of the questions code. – Daniel Jour Mar 05 '16 at 23:06