Implement a platform independent re-entrant sort functionBRL-CAD
Status: ClosedTime to complete: 72 hrs Mentors: Daniel RossbergTags: C

The classic C library qsort() does not support a context parameter.  A work around is to store the context information in a static variable.  However, this solution is not thread save and may result in unpredictable behavior.

There are platform specific sort functions qsort_r() in incompatible versions for BSD and GNU and qsort_s() for MSVC.  Your task is to implement a bu_sort() function for BRL-CAD which is platform independent.

Code:

  • src/libbu/sort.c

The new sort function could look like this:
void bu_sort(genptr_t array, size_t nummemb, size_t sizememb,
   int (*compare)(const_genptr_t, const_genptr_t, genptr_t),
   genptr_t context);

Uploaded Work
File name/URLFile sizeDate submitted
bu_sort.patch2.4 KBDecember 14 2013 17:06 UTC
bu_sort.patch5.7 KBDecember 16 2013 21:50 UTC
bu_sort.patch7.3 KBDecember 17 2013 20:09 UTC
bu_sort.patch7.3 KBDecember 18 2013 15:25 UTC
Comments
Johannes Schulteon December 11 2013 20:14 UTCTask Claimed

I would like to work on this task.

Mandeep Kaur on December 12 2013 03:47 UTCTask Assigned

This task has been assigned to Johannes Schulte. You have 72 hours to complete this task, good luck!

Johannes Schulteon December 14 2013 17:14 UTC

I didn't push the patch to the tree, because I couldn't test it on Win and Mac. Nevertheless, if the code looks reasonable to you, or you can test it, I can do the commit afterwards.


BTW, did you create this task on purpose a second time? (https://google-melange.appspot.com/gci/task/view/google/gci2013/4993291800018944)


 

Johannes Schulteon December 14 2013 17:14 UTCReady for review

The work on this task is ready to be reviewed.

Johannes Schulteon December 14 2013 19:02 UTC

Just saw, that I missed one genptr_t use, so, though it shouldn't influence the function, this is the fixed version: http://pastebin.com/aQ6sjHaL

Melange on December 15 2013 03:47 UTCNo more Work can be submitted

Melange has detected that the deadline has passed and no more work can be submitted. The submitted work should be reviewed.

Sean on December 15 2013 04:59 UTCTask Needs More Work

One of the mentors has sent this task back for more work. Talk to the mentor(s) assigned to this task to satisfy the requirements needed to complete this task, submit your work again and mark the task as complete once you re-submit your work.

Sean on December 15 2013 05:09 UTCnot so simple

There are several issues I see with this implementation.


First and foremost is that you use preprocessor platform identifiers and version numbers to determine whether you can call qsort_r() and qsort_s().  See our HACKING file for details, but that  is not a desireable approach.  Use of those function sshould be tied to feature identifiers that are tested for by cmake (e.g., you can test in the top-level CMakeLists.txt file whether qsort_s is available, it'll define HAVE_QSORT_S).  Testing for qsort_r is a little tricky, but doable to figure out which of either is available.


That brings me to the second point, you have no failover implementation (which you may want to just start with first instead of figuring out the CMake testing you'd need).  To be truely portable, there needs to be an #else case that still does the sorting, otherwise we have an empty function that will do nothing and result in bad behavior.


The last point is stylistic.  The indentations are off.  Notably, you have two-char indent on the struct and the sort callback function, and tabs or something else going on in bu_sort().  You also have spaces before the '#' preprocessor directives, which is not portable.  See HACKING for details and an example of our expected format (this is critical if you're to commit it yourself as we take pride in consistency), or browse some of the other files.


 

Johannes Schulteon December 15 2013 11:34 UTC

so, did I understand right, that reimplementing qsort is the way to go? Is then the cmake testing and usage of qsort_r and qsort_s still necessary, or can I use this implementation for every platform ?

Daniel Rossberg on December 15 2013 15:31 UTCUsing the BSD implementation of qsort_r()?

Only an idea, but the license of the BSD implementation should allow to use the code in BRL-CAD's LGPL libbu library.

Daniel Rossberg on December 15 2013 15:57 UTCDeadline extended

The deadline of the task has been extended with 2 days and 0 hours.

Daniel Rossberg on December 15 2013 16:14 UTCDuplicated task

I tried to create the task on different ways.  One was directly in google-melange and another via a Google docs form provided by Sean.  Now both are visible.

Johannes Schulteon December 16 2013 21:50 UTCReady for review

The work on this task is ready to be reviewed.

Johannes Schulteon December 16 2013 21:51 UTC

As Daniel proposed, I used BSD's implementation. Is any source naming necessary for this in the source file?

Johannes Schulteon December 16 2013 22:17 UTC

BTW, what is status quo concernig genptr_t. On the maillist I read, that it's deprecated, but in task specification it's required. For now I used void *, is this right or should I go back to genptr_t?

Sean on December 17 2013 04:05 UTCTask Needs More Work

One of the mentors has sent this task back for more work. Talk to the mentor(s) assigned to this task to satisfy the requirements needed to complete this task, submit your work again and mark the task as complete once you re-submit your work.

Sean on December 17 2013 04:05 UTCDeadline extended

The deadline of the task has been extended with 1 days and 0 hours.

Sean on December 17 2013 04:24 UTCcredit where credit is due

Johannes, this is looking really good but there is one major problem with the patch.  You used code from BSD as-is, but you do not credit them anywhere.  This is technically illegal and morally crummy to do too.. I'm sure that wasn't your intention, and fortunately easy to fix.  You should always "cite your sources" whether you are writing prose or writing code, even if the license doesn't require it.


The fix: You can put their entire legal comment block that was at the top of their file right there in the file before their sources (after our legal comment header block).  You should put a comment in there too to say what sources this code was copied/derived from [wherever you got them from, specifically].  See src/libbu/fnmatch.c for an example.


That said, there are also numerous issues with the copy-pasting that must be addressed.  Their code does not comply with our code conventions.  So while you can use them and that gives you an advantage, you must update them to our conventions.  A few I see right away:



  • macros should be in CAPS

  • functions must be defined/declared per ANSI C, not KR

  • non-public functions should be declared static

  • your include/bu.h decl doesn't match your impl (genptr_t)


The usage of sizeof(long) is also highly suspect, may not be portable, but I don't see any blatant problems at the moment.  You might want to try a few of the other BSD's (there are at least 3 or 4 implementations to consider) to see if any others avoid performing runtime type sizing.


 

Daniel Rossberg on December 17 2013 07:49 UTCDeprecated genptr_t

Using void* is Ok.

Johannes Schulteon December 17 2013 20:09 UTCReady for review

The work on this task is ready to be reviewed.

Johannes Schulteon December 17 2013 20:10 UTCNext try

Thanks for your explanation, thats what my "source naming"-question was all about.

Johannes Schulteon December 17 2013 20:17 UTC

Oops, shame on me. That's what happens, if you forget to build a last time before commiting. This version should work : http://pastebin.com/aDzUXhwZ

Sean on December 18 2013 05:23 UTCTask Needs More Work

One of the mentors has sent this task back for more work. Talk to the mentor(s) assigned to this task to satisfy the requirements needed to complete this task, submit your work again and mark the task as complete once you re-submit your work.

Sean on December 18 2013 05:25 UTCgo ahead and upload

Go ahead and upload the patch update here so we can track it with the task, but a quick review and it looked good to me.


 

Daniel Rossberg on December 18 2013 07:29 UTCDeadline extended

The deadline of the task has been extended with 1 days and 0 hours.

Johannes Schulteon December 18 2013 15:25 UTCReady for review

The work on this task is ready to be reviewed.

Sean on December 18 2013 20:48 UTCTask Closed

Congratulations, this task has been completed successfully.

Sean on December 18 2013 20:50 UTCexcellent, unit test

Johannes, this looks perfect now,  Please commit it yourself (great first commit!).


A unit test for this would be a great follow-on task.  Using this function where we sort things would be another.


 

Johannes Schulteon December 18 2013 22:29 UTC

Both tasks, especially the replacement of old qsort uses, sound interesting. It would be great, if you create them.

Sean on December 18 2013 23:48 UTCfollow-on tasks created

Numerous follow-on tasks related to this have been created including unit test and conversion of qsort to bu_sort.