I read this somewhere (not tested, but makes since), fcntl in notorious for perfomance issues, but in your case I think that you can get around this by not allowing F_SETLKW to do the lock checking. Instead if you used F_GETLK it may speed things up. Also you may try SYSVSEM2 instead of fcntl,
this paper outlines some of the issues well.
Hope that this helps,
Cameron
NOTE: For the most part I am talking way over my head, so I could be very wrong with everything that I said, please take take my words as goodfaith suggestions and maybe a point in a better direction.