aboutsummaryrefslogtreecommitdiff
path: root/print_foobar_alternately.c
blob: 6892b2c440ddd6b3139cde859e5df3c73ffa1c0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// 1115. Print FooBar Alternately
#include "leetcode.h"
#include <semaphore.h>

/*
 * suppose you are given the following code:
  class FooBar {
    public void foo() {
      for (int i = 0; i < n; i++) {
        print("foo");
      }
    }

    public void bar() {
      for (int i = 0; i < n; i++) {
        print("bar");
      }
    }
  }
 * the same instance of 'FooBar' will be passed to two different threads: thread
 * 'a' will call 'foo()' and thread 'b' will call 'bar()'. modify the given
 * program to output "foobar" 'n' times.
 */

typedef struct {
  int n;
  sem_t s_foo;
  sem_t s_bar;
} FooBar;

// Function declarations. Do not change or remove this line
void printFoo();
void printBar();

FooBar *fooBarCreate(int n) {
  FooBar *obj = (FooBar *)malloc(sizeof(FooBar));
  obj->n = n;
  sem_init(&obj->s_foo, 0, 0);
  sem_init(&obj->s_bar, 0, 1);
  return obj;
}

void foo(FooBar *obj) {
  for (int i = 0; i < obj->n; i++) {
    sem_wait(&obj->s_bar);
    // printFoo() outputs "foo". Do not change or remove this line.
    printFoo();
    sem_post(&obj->s_foo);
  }
}

void bar(FooBar *obj) {
  for (int i = 0; i < obj->n; i++) {
    sem_wait(&obj->s_foo);
    // printBar() outputs "bar". Do not change or remove this line.
    printBar();
    sem_post(&obj->s_bar);
  }
}

void fooBarFree(FooBar *obj) {
  sem_destroy(&obj->s_foo);
  sem_destroy(&obj->s_bar);
  if (obj)
    free(obj);
}

int main() {
  FooBar *f1 = fooBarCreate(1);
  FooBar *f2 = fooBarCreate(2);
  foo(f1);
  bar(f1);
  foo(f2);
  bar(f2);
  fooBarFree(f1);
  fooBarFree(f2);
}

void printFoo() { printf("foo"); }

void printBar() { printf("bar"); }