Projects
Wiki     Timeline     Browser     Search     New Ticket     Bug Reports

Ticket #37 (reopened defect)

Opened 5 months ago

Last modified 4 months ago

GCD queue overflowed?

Reported by: victor.tsang@… Owned by:
Priority: major Milestone: MacOSX
Version: 1.0 Keywords:
Cc:

Description

I found that the queue may overflow and lost some task blocks.

As attached, my test program is to create a block to submit lots of tasks into concurrent queue. The task is just do something eating up CPU and then queue a finishing task into a serial queue. The finishing task is to decrement a count and that that should go down to zero if everything is correct.

However, if the number of tasks is big(?), such as 100,000 or 1,000,000, the count cannot go back to zero... it looks like that some tasks are missed. As dispatch_async() is a void function, the program cannot get the queue overflow information and perform retry or any other error correction.

I tested the code in both
1. MacBookPro? i7 4-core CPU, Lion, with clang3.0 / Xcode 4.2.1
2. the same Lion machine under Parallels VM with 4-core CPU, FreeBSD 8.2 with clang3.0.

Attachments

test_GCD.cpp Download (1.8 KB) - added by victor.tsang@… 5 months ago.
Test program to illustrate the GCD bug.

Change History

Changed 5 months ago by victor.tsang@…

Test program to illustrate the GCD bug.

follow-up: ↓ 2   Changed 4 months ago by dsteffen@…

  • status changed from new to closed
  • resolution set to invalid

the bug is in your code, 'tasks' is being decremented in an asynchronous block (block 3), so the loop condition (i < tasks) becomes false sooner than you seem to expect.

in reply to: ↑ 1   Changed 4 months ago by victor.tsang@…

  • status changed from closed to reopened
  • resolution invalid deleted

Replying to dsteffen@…:

the bug is in your code, 'tasks' is being decremented in an asynchronous block (block 3), so the loop condition (i < tasks) becomes false sooner than you seem to expect.

Thank you very much for your attention.

However, the (block 3) is dispatched into a serial queue defined in line 15.

q = dispatch_queue_create("test001",0);

What I was thinking is that, "block 1" is generating lots of "block 2" and "block 2" tasks should be executed async in the global queue, by controlled number of background threads.

Each of those "block 2" tasks will submit a "block 3" task into a serial queue "test001" (defined in line 15 of the code) which will decrement the counter.

Since the "test001" queue is a serial queue, there is no need to mutex guard the "tasks" variable defined in line 8. Each "block 3" will be executed one by one.

So, say, block 1 generated 1 million block 2, and these block 2 will in total generated 1 million block 3. These 1 million block 3 in the serial queue "test001" will decrease the block variable "tasks" from 1000000 to 0.

The problem is, the tasks variable cannot count down to zero.

Note: See TracTickets for help on using tickets.